From: Sasha Levin Date: Sat, 13 Dec 2025 09:23:52 +0000 (-0500) Subject: Fixes for all trees X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=HEAD;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-5.10/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..fefda5a4f0 --- /dev/null +++ b/queue-5.10/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 3038bf9cb041c1ebf1f2a291fd3f6d4643d0fbd0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 2ac48cda5b201..eae7efae3b5cf 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-5.10/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-5.10/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..b4b26ab059 --- /dev/null +++ b/queue-5.10/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 055140f747be8163c1d172e03fc2d2c5fc0e8bc5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 821150dcb9762..7c3d98fae457d 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1423,6 +1423,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-5.10/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-5.10/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..b589ae2134 --- /dev/null +++ b/queue-5.10/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From ef4bb9c8c4901a808f3ac74fa775905767fa52b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 0f4e4c3847b75..83e8d89cc4857 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-5.10/backlight-led_bl-take-led_access-lock-when-required.patch b/queue-5.10/backlight-led_bl-take-led_access-lock-when-required.patch new file mode 100644 index 0000000000..f445cab815 --- /dev/null +++ b/queue-5.10/backlight-led_bl-take-led_access-lock-when-required.patch @@ -0,0 +1,73 @@ +From baed2033e0bf8f1ea008f2e9f9cdb6dc157f7e30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jun 2023 17:02:49 +0100 +Subject: backlight: led_bl: Take led_access lock when required + +From: Mans Rullgard + +[ Upstream commit a33677b9211b6c328ad359b072043af94f7c9592 ] + +The led_access lock must be held when calling led_sysfs_enable() and +led_sysfs_disable(). This fixes warnings such as this: + +[ 2.432495] ------------[ cut here ]------------ +[ 2.437316] WARNING: CPU: 0 PID: 22 at drivers/leds/led-core.c:349 led_sysfs_disable+0x54/0x58 +[ 2.446105] Modules linked in: +[ 2.449218] CPU: 0 PID: 22 Comm: kworker/u2:1 Not tainted 6.3.8+ #1 +[ 2.456268] Hardware name: Generic AM3517 (Flattened Device Tree) +[ 2.462402] Workqueue: events_unbound deferred_probe_work_func +[ 2.468353] unwind_backtrace from show_stack+0x10/0x14 +[ 2.473632] show_stack from dump_stack_lvl+0x24/0x2c +[ 2.478759] dump_stack_lvl from __warn+0x9c/0xc4 +[ 2.483551] __warn from warn_slowpath_fmt+0x64/0xc0 +[ 2.488586] warn_slowpath_fmt from led_sysfs_disable+0x54/0x58 +[ 2.494567] led_sysfs_disable from led_bl_probe+0x20c/0x3b0 +[ 2.500305] led_bl_probe from platform_probe+0x5c/0xb8 +[ 2.505615] platform_probe from really_probe+0xc8/0x2a0 +[ 2.510986] really_probe from __driver_probe_device+0x88/0x19c +[ 2.516967] __driver_probe_device from driver_probe_device+0x30/0xcc +[ 2.523498] driver_probe_device from __device_attach_driver+0x94/0xc4 +[ 2.530090] __device_attach_driver from bus_for_each_drv+0x80/0xcc +[ 2.536437] bus_for_each_drv from __device_attach+0xf8/0x19c +[ 2.542236] __device_attach from bus_probe_device+0x8c/0x90 +[ 2.547973] bus_probe_device from deferred_probe_work_func+0x80/0xb0 +[ 2.554504] deferred_probe_work_func from process_one_work+0x228/0x4c0 +[ 2.561187] process_one_work from worker_thread+0x1fc/0x4d0 +[ 2.566925] worker_thread from kthread+0xb4/0xd0 +[ 2.571685] kthread from ret_from_fork+0x14/0x2c +[ 2.576446] Exception stack(0xd0079fb0 to 0xd0079ff8) +[ 2.581573] 9fa0: 00000000 00000000 00000000 00000000 +[ 2.589813] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 2.598052] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 +[ 2.604888] ---[ end trace 0000000000000000 ]--- + +Signed-off-by: Mans Rullgard +Reviewed-by: Daniel Thompson +Link: https://lore.kernel.org/r/20230619160249.10414-1-mans@mansr.com +Signed-off-by: Lee Jones +Stable-dep-of: 9341d6698f4c ("backlight: led-bl: Add devlink to supplier LEDs") +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 1020e4405a4d1..0f4e4c3847b75 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,8 +209,11 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + +- for (i = 0; i < priv->nb_leds; i++) ++ for (i = 0; i < priv->nb_leds; i++) { ++ mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); ++ mutex_unlock(&priv->leds[i]->led_access); ++ } + + backlight_update_status(priv->bl_dev); + +-- +2.51.0 + diff --git a/queue-5.10/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-5.10/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..b5c0f3cac3 --- /dev/null +++ b/queue-5.10/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From 729932076449d3486a13d7d8e27baf4e2bb52a42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-5.10/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch b/queue-5.10/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch new file mode 100644 index 0000000000..433466b72d --- /dev/null +++ b/queue-5.10/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch @@ -0,0 +1,111 @@ +From f8e16eebf617cd521687a5287495858a5c7853fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Apr 2022 11:56:48 +0200 +Subject: clk: renesas: r9a06g032: Export function to set dmamux + +From: Miquel Raynal + +[ Upstream commit 885525c1e7e27ea6207d648a8db20dfbbd9e4238 ] + +The dmamux register is located within the system controller. + +Without syscon, we need an extra helper in order to give write access to +this register to a dmamux driver. + +Signed-off-by: Miquel Raynal +Acked-by: Stephen Boyd +Reviewed-by: Geert Uytterhoeven +Acked-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20220427095653.91804-5-miquel.raynal@bootlin.com +Signed-off-by: Vinod Koul +Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 35 ++++++++++++++++++- + include/linux/soc/renesas/r9a06g032-sysctrl.h | 11 ++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) + create mode 100644 include/linux/soc/renesas/r9a06g032-sysctrl.h + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 285f6ac25372d..65cd6ed68923e 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -20,9 +20,12 @@ + #include + #include + #include ++#include + #include + #include + ++#define R9A06G032_SYSCTRL_DMAMUX 0xA0 ++ + struct r9a06g032_gate { + u16 gate, reset, ready, midle, + scon, mirack, mistat; +@@ -315,6 +318,30 @@ struct r9a06g032_priv { + void __iomem *reg; + }; + ++static struct r9a06g032_priv *sysctrl_priv; ++ ++/* Exported helper to access the DMAMUX register */ ++int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) ++{ ++ unsigned long flags; ++ u32 dmamux; ++ ++ if (!sysctrl_priv) ++ return -EPROBE_DEFER; ++ ++ spin_lock_irqsave(&sysctrl_priv->lock, flags); ++ ++ dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); ++ dmamux &= ~mask; ++ dmamux |= val & mask; ++ writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); ++ ++ spin_unlock_irqrestore(&sysctrl_priv->lock, flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_set_dmamux); ++ + /* register/bit pairs are encoded as an uint16_t */ + static void + clk_rdesc_set(struct r9a06g032_priv *clocks, +@@ -961,7 +988,13 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (error) + return error; + +- return r9a06g032_add_clk_domain(dev); ++ error = r9a06g032_add_clk_domain(dev); ++ if (error) ++ return error; ++ ++ sysctrl_priv = clocks; ++ ++ return 0; + } + + static const struct of_device_id r9a06g032_match[] = { +diff --git a/include/linux/soc/renesas/r9a06g032-sysctrl.h b/include/linux/soc/renesas/r9a06g032-sysctrl.h +new file mode 100644 +index 0000000000000..066dfb15cbddd +--- /dev/null ++++ b/include/linux/soc/renesas/r9a06g032-sysctrl.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ ++#define __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ ++ ++#ifdef CONFIG_CLK_R9A06G032 ++int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val); ++#else ++static inline int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) { return -ENODEV; } ++#endif ++ ++#endif /* __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ */ +-- +2.51.0 + diff --git a/queue-5.10/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-5.10/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..5dd86d905a --- /dev/null +++ b/queue-5.10/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 965e0e8f4f387e39aa13db221113f665d925ff30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index b3fd97615fc4c..9807fd0adb6c3 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -969,9 +969,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-5.10/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch b/queue-5.10/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch new file mode 100644 index 0000000000..c77c12fd56 --- /dev/null +++ b/queue-5.10/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch @@ -0,0 +1,80 @@ +From 2f084b5c465e5f8b57e01645551058b45c502016 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 13:00:39 -0700 +Subject: compiler-gcc.h: Define __SANITIZE_ADDRESS__ under hwaddress sanitizer + +From: Kees Cook + +[ Upstream commit 9a48e7564ac83fb0f1d5b0eac5fe8a7af62da398 ] + +When Clang is using the hwaddress sanitizer, it sets __SANITIZE_ADDRESS__ +explicitly: + + #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) + /* Emulate GCC's __SANITIZE_ADDRESS__ flag */ + #define __SANITIZE_ADDRESS__ + #endif + +Once hwaddress sanitizer was added to GCC, however, a separate define +was created, __SANITIZE_HWADDRESS__. The kernel is expecting to find +__SANITIZE_ADDRESS__ in either case, though, and the existing string +macros break on supported architectures: + + #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ + !defined(__SANITIZE_ADDRESS__) + +where as other architectures (like arm32) have no idea about hwaddress +sanitizer and just check for __SANITIZE_ADDRESS__: + + #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) + +This would lead to compiler foritfy self-test warnings when building +with CONFIG_KASAN_SW_TAGS=y: + +warning: unsafe memmove() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memmove.c +warning: unsafe memcpy() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memcpy.c +... + +Sort this out by also defining __SANITIZE_ADDRESS__ in GCC under the +hwaddress sanitizer. + +Suggested-by: Arnd Bergmann +Cc: Nick Desaulniers +Cc: Andrew Morton +Cc: Will Deacon +Cc: Arvind Sankar +Cc: Masahiro Yamada +Cc: llvm@lists.linux.dev +Signed-off-by: Kees Cook +Reviewed-by: Nathan Chancellor +Acked-by: Miguel Ojeda +Reviewed-by: Marco Elver +Link: https://lore.kernel.org/r/20211020200039.170424-1-keescook@chromium.org +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-gcc.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index ae9a8e17287ce..faf0fd509cb5a 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -140,6 +140,14 @@ + #define __no_sanitize_coverage + #endif + ++/* ++ * Treat __SANITIZE_HWADDRESS__ the same as __SANITIZE_ADDRESS__ in the kernel, ++ * matching the defines used by Clang. ++ */ ++#ifdef __SANITIZE_HWADDRESS__ ++#define __SANITIZE_ADDRESS__ ++#endif ++ + /* + * Turn individual warnings and errors on and off locally, depending + * on version. +-- +2.51.0 + diff --git a/queue-5.10/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-5.10/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..89eaec82a4 --- /dev/null +++ b/queue-5.10/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From 697167af80ad3ef3b151247aa127ad5f71d3fc30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 33e77d846caa8..ef0e56642a078 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -138,12 +139,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-5.10/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-5.10/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..af94e090b2 --- /dev/null +++ b/queue-5.10/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From 3a4538c93dc595f6293f0db879f3df6357299fe5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index 6140e49273226..5754dc88c684c 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-5.10/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-5.10/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..69460db65c --- /dev/null +++ b/queue-5.10/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 7bbf969e3d7e9177ffc68eda450bc3d4b533d1a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 9dd41eaf32cb5..3cc61bb6f8967 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -961,10 +961,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-5.10/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-5.10/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..481d7b6643 --- /dev/null +++ b/queue-5.10/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From 32cdd625a881af832fd4bf35bfb5c9ddd6682dcb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 6134432e4918d..2260d5abf1ae8 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -64,7 +64,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + int ret; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-5.10/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-5.10/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..c358678bc9 --- /dev/null +++ b/queue-5.10/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From 8111c4ee858af254f6bf998995896ead890bb0bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index 575bc331716e8..f860ff1db648f 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -94,7 +94,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-5.10/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-5.10/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..1d207ee22e --- /dev/null +++ b/queue-5.10/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From 6c6a2280d69e587f4cf092edfb27c1dd204bd2ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 4cb1872c9af43..b1ad339165e41 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -473,7 +473,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-5.10/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-5.10/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..4d219bf154 --- /dev/null +++ b/queue-5.10/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From e455d2fe264a34f5616346c7966ac9b682de0fb1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 65042bef41e4e..3270a8e3c3cf7 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -602,6 +602,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -646,15 +664,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -670,15 +679,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-5.10/ext4-minor-defrag-code-improvements.patch b/queue-5.10/ext4-minor-defrag-code-improvements.patch new file mode 100644 index 0000000000..ed2250cff1 --- /dev/null +++ b/queue-5.10/ext4-minor-defrag-code-improvements.patch @@ -0,0 +1,79 @@ +From 6239ac08fb95705b695aeb689d1914031972dc6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jul 2022 12:39:10 -0400 +Subject: ext4: minor defrag code improvements + +From: Eric Whitney + +[ Upstream commit d412df530f77d0f61c41b83f925997452fc3944c ] + +Modify the error returns for two file types that can't be defragged to +more clearly communicate those restrictions to a caller. When the +defrag code is applied to swap files, return -ETXTBSY, and when applied +to quota files, return -EOPNOTSUPP. Move an extent tree search whose +results are only occasionally required to the site always requiring them +for improved efficiency. Address a few typos. + +Signed-off-by: Eric Whitney +Link: https://lore.kernel.org/r/20220722163910.268564-1-enwlinux@gmail.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: a2e5a3cea4b1 ("ext4: correct the checking of quota files before moving extents") +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 661a8544d7817..4cb1872c9af43 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -466,19 +466,17 @@ mext_check_arguments(struct inode *orig_inode, + if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode)) + return -EPERM; + +- /* Ext4 move extent does not support swapfile */ ++ /* Ext4 move extent does not support swap files */ + if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { +- ext4_debug("ext4 move extent: The argument files should " +- "not be swapfile [ino:orig %lu, donor %lu]\n", ++ ext4_debug("ext4 move extent: The argument files should not be swap files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); +- return -EBUSY; ++ return -ETXTBSY; + } + + if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { +- ext4_debug("ext4 move extent: The argument files should " +- "not be quota files [ino:orig %lu, donor %lu]\n", ++ ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); +- return -EBUSY; ++ return -EOPNOTSUPP; + } + + /* Ext4 move extent supports only extent based file */ +@@ -626,11 +624,11 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, + if (ret) + goto out; + ex = path[path->p_depth].p_ext; +- next_blk = ext4_ext_next_allocated_block(path); + cur_blk = le32_to_cpu(ex->ee_block); + cur_len = ext4_ext_get_actual_len(ex); + /* Check hole before the start pos */ + if (cur_blk + cur_len - 1 < o_start) { ++ next_blk = ext4_ext_next_allocated_block(path); + if (next_blk == EXT_MAX_BLOCKS) { + o_start = o_end; + ret = -ENODATA; +@@ -659,7 +657,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, + donor_page_index = d_start >> (PAGE_SHIFT - + donor_inode->i_blkbits); + offset_in_page = o_start % blocks_per_page; +- if (cur_len > blocks_per_page- offset_in_page) ++ if (cur_len > blocks_per_page - offset_in_page) + cur_len = blocks_per_page - offset_in_page; + /* + * Up semaphore to avoid following problems: +-- +2.51.0 + diff --git a/queue-5.10/ext4-remove-unused-return-value-of-__mb_check_buddy.patch b/queue-5.10/ext4-remove-unused-return-value-of-__mb_check_buddy.patch new file mode 100644 index 0000000000..7e27f21578 --- /dev/null +++ b/queue-5.10/ext4-remove-unused-return-value-of-__mb_check_buddy.patch @@ -0,0 +1,63 @@ +From 0a20adc0121268b18b4cf6a0d20fbb9844e31c8e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Jan 2024 17:20:54 +0800 +Subject: ext4: remove unused return value of __mb_check_buddy + +From: Kemeng Shi + +[ Upstream commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 ] + +Remove unused return value of __mb_check_buddy. + +Signed-off-by: Kemeng Shi +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240105092102.496631-2-shikemeng@huaweicloud.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation") +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 60c56a39798cc..65042bef41e4e 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -602,7 +602,7 @@ do { \ + } \ + } while (0) + +-static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, ++static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { + struct super_block *sb = e4b->bd_sb; +@@ -621,7 +621,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + void *buddy2; + + if (e4b->bd_info->bb_check_counter++ % 10) +- return 0; ++ return; + + while (order > 1) { + buddy = mb_find_buddy(e4b, order, &max); +@@ -686,7 +686,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + + grp = ext4_get_group_info(sb, e4b->bd_group); + if (!grp) +- return NULL; ++ return; + list_for_each(cur, &grp->bb_prealloc_list) { + ext4_group_t groupnr; + struct ext4_prealloc_space *pa; +@@ -696,7 +696,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + for (i = 0; i < pa->pa_len; i++) + MB_CHECK_ASSERT(mb_test_bit(k + i, buddy)); + } +- return 0; + } + #undef MB_CHECK_ASSERT + #define mb_check_buddy(e4b) __mb_check_buddy(e4b, \ +-- +2.51.0 + diff --git a/queue-5.10/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-5.10/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..39fdb9bb98 --- /dev/null +++ b/queue-5.10/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From 9bb9c9421486c1368668aeae303c7e2bc615d57b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index eda448b7a0c9d..fd26d368fdf5c 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -676,7 +676,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -756,6 +756,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-5.10/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-5.10/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..ca77b1721a --- /dev/null +++ b/queue-5.10/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From f9a833e66cc5a2358558d34d4b592719f7fa6c36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index d9dcc20945c6a..32b1ca4e10508 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -160,8 +160,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-5.10/i3c-allow-of-alias-based-persistent-bus-numbering.patch b/queue-5.10/i3c-allow-of-alias-based-persistent-bus-numbering.patch new file mode 100644 index 0000000000..dddfedad95 --- /dev/null +++ b/queue-5.10/i3c-allow-of-alias-based-persistent-bus-numbering.patch @@ -0,0 +1,121 @@ +From 87a19890a13e0e5f2c13b387973d7153bfc0681f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Apr 2023 17:41:49 +0800 +Subject: i3c: Allow OF-alias-based persistent bus numbering + +From: Jeremy Kerr + +[ Upstream commit 7dc2e0a875645a79f5c1c063019397e8e94008f5 ] + +Parse the /aliases node to assign any fixed bus numbers, as is done with +the i2c subsystem. Numbering for non-aliased busses will start after the +highest fixed bus number. + +This allows an alias node such as: + + aliases { + i3c0 = &bus_a, + i3c4 = &bus_b, + }; + +to set the numbering for a set of i3c controllers: + + /* fixed-numbered bus, assigned "i3c-0" */ + bus_a: i3c-master { + }; + + /* another fixed-numbered bus, assigned "i3c-4" */ + bus_b: i3c-master { + }; + + /* dynamic-numbered bus, likely assigned "i3c-5" */ + bus_c: i3c-master { + }; + +If no i3c device aliases are present, the numbering will stay as-is, +starting from 0. + +Signed-off-by: Jeremy Kerr +Link: https://lore.kernel.org/r/20230405094149.1513209-1-jk@codeconstruct.com.au +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index f9f96c4bb9002..332b1f02e6ea5 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -21,6 +21,7 @@ + + static DEFINE_IDR(i3c_bus_idr); + static DEFINE_MUTEX(i3c_core_lock); ++static int __i3c_first_dynamic_bus_num; + + /** + * i3c_bus_maintenance_lock - Lock the bus for a maintenance operation +@@ -466,9 +467,9 @@ static void i3c_bus_cleanup(struct i3c_bus *i3cbus) + mutex_unlock(&i3c_core_lock); + } + +-static int i3c_bus_init(struct i3c_bus *i3cbus) ++static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np) + { +- int ret; ++ int ret, start, end, id = -1; + + init_rwsem(&i3cbus->lock); + INIT_LIST_HEAD(&i3cbus->devs.i2c); +@@ -476,8 +477,19 @@ static int i3c_bus_init(struct i3c_bus *i3cbus) + i3c_bus_init_addrslots(i3cbus); + i3cbus->mode = I3C_BUS_MODE_PURE; + ++ if (np) ++ id = of_alias_get_id(np, "i3c"); ++ + mutex_lock(&i3c_core_lock); +- ret = idr_alloc(&i3c_bus_idr, i3cbus, 0, 0, GFP_KERNEL); ++ if (id >= 0) { ++ start = id; ++ end = start + 1; ++ } else { ++ start = __i3c_first_dynamic_bus_num; ++ end = 0; ++ } ++ ++ ret = idr_alloc(&i3c_bus_idr, i3cbus, start, end, GFP_KERNEL); + mutex_unlock(&i3c_core_lock); + + if (ret < 0) +@@ -2649,7 +2661,7 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus); ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); + if (ret) + return ret; + +@@ -2858,8 +2870,16 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) + + static int __init i3c_init(void) + { +- int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); ++ int res; ++ ++ res = of_alias_get_highest_id("i3c"); ++ if (res >= 0) { ++ mutex_lock(&i3c_core_lock); ++ __i3c_first_dynamic_bus_num = res + 1; ++ mutex_unlock(&i3c_core_lock); ++ } + ++ res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); + if (res) + return res; + +-- +2.51.0 + diff --git a/queue-5.10/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-5.10/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..ea9b649cd4 --- /dev/null +++ b/queue-5.10/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From cf50bc9fbb79bbe950227e99f77f59dec64f7571 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 507fb6d26d330..527bea0ffcd7f 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2661,10 +2661,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2672,6 +2668,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-5.10/i3c-master-inherit-dma-masks-and-parameters-from-par.patch b/queue-5.10/i3c-master-inherit-dma-masks-and-parameters-from-par.patch new file mode 100644 index 0000000000..3ce0dae903 --- /dev/null +++ b/queue-5.10/i3c-master-inherit-dma-masks-and-parameters-from-par.patch @@ -0,0 +1,40 @@ +From 999ababfb403459469f4ccb51f0d1ef4dd0c0bad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:53 +0300 +Subject: i3c: master: Inherit DMA masks and parameters from parent device + +From: Jarkko Nikula + +[ Upstream commit 0c35691551387e060e6ae7a6652b4101270c73cf ] + +Copy the DMA masks and parameters for an I3C master device from parent +device so that the master device has them set for the DMA buffer and +mapping API. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-2-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 332b1f02e6ea5..507fb6d26d330 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2668,6 +2668,10 @@ int i3c_master_register(struct i3c_master_controller *master, + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + ++ master->dev.dma_mask = parent->dma_mask; ++ master->dev.coherent_dma_mask = parent->coherent_dma_mask; ++ master->dev.dma_parms = parent->dma_parms; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-5.10/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch b/queue-5.10/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch new file mode 100644 index 0000000000..9ce2c47232 --- /dev/null +++ b/queue-5.10/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch @@ -0,0 +1,104 @@ +From 9b27a1f1f57eb94b0028bf15f09d3ba7f5031121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jan 2022 17:48:15 +0000 +Subject: i3c: remove i2c board info from i2c_dev_desc + +From: Jamie Iles + +[ Upstream commit 31b9887c7258ca47d9c665a80f19f006c86756b1 ] + +I2C board info is only required during adapter setup so there is no +requirement to keeping a pointer to it once running. To support dynamic +device addition we can't rely on board info - user-space creation +through sysfs won't have a boardinfo. + +Cc: Alexandre Belloni +Signed-off-by: Jamie Iles +Signed-off-by: Alexandre Belloni +Link: https://lore.kernel.org/r/20220117174816.1963463-2-quic_jiles@quicinc.com +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 18 ++++++++++-------- + include/linux/i3c/master.h | 1 - + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 203b7497b52dc..e3fffc5015c10 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -656,7 +656,7 @@ static void i3c_master_free_i2c_dev(struct i2c_dev_desc *dev) + + static struct i2c_dev_desc * + i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, +- const struct i2c_dev_boardinfo *boardinfo) ++ u16 addr, u8 lvr) + { + struct i2c_dev_desc *dev; + +@@ -665,9 +665,8 @@ i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, + return ERR_PTR(-ENOMEM); + + dev->common.master = master; +- dev->boardinfo = boardinfo; +- dev->addr = boardinfo->base.addr; +- dev->lvr = boardinfo->lvr; ++ dev->addr = addr; ++ dev->lvr = lvr; + + return dev; + } +@@ -741,7 +740,7 @@ i3c_master_find_i2c_dev_by_addr(const struct i3c_master_controller *master, + struct i2c_dev_desc *dev; + + i3c_bus_for_each_i2cdev(&master->bus, dev) { +- if (dev->boardinfo->base.addr == addr) ++ if (dev->addr == addr) + return dev; + } + +@@ -1731,7 +1730,9 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) + i2cboardinfo->base.addr, + I3C_ADDR_SLOT_I2C_DEV); + +- i2cdev = i3c_master_alloc_i2c_dev(master, i2cboardinfo); ++ i2cdev = i3c_master_alloc_i2c_dev(master, ++ i2cboardinfo->base.addr, ++ i2cboardinfo->lvr); + if (IS_ERR(i2cdev)) { + ret = PTR_ERR(i2cdev); + goto err_detach_devs; +@@ -2220,6 +2221,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + { + struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master); + struct i2c_dev_desc *i2cdev; ++ struct i2c_dev_boardinfo *i2cboardinfo; + int ret; + + adap->dev.parent = master->dev.parent; +@@ -2239,8 +2241,8 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + * We silently ignore failures here. The bus should keep working + * correctly even if one or more i2c devices are not registered. + */ +- i3c_bus_for_each_i2cdev(&master->bus, i2cdev) +- i2cdev->dev = i2c_new_client_device(adap, &i2cdev->boardinfo->base); ++ list_for_each_entry(i2cboardinfo, &master->boardinfo.i2c, node) ++ i2cdev->dev = i2c_new_client_device(adap, &i2cboardinfo->base); + + return 0; + } +diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h +index ea3781d730064..b31170e37655f 100644 +--- a/include/linux/i3c/master.h ++++ b/include/linux/i3c/master.h +@@ -85,7 +85,6 @@ struct i2c_dev_boardinfo { + */ + struct i2c_dev_desc { + struct i3c_i2c_dev_desc common; +- const struct i2c_dev_boardinfo *boardinfo; + struct i2c_client *dev; + u16 addr; + u8 lvr; +-- +2.51.0 + diff --git a/queue-5.10/i3c-support-dynamically-added-i2c-devices.patch b/queue-5.10/i3c-support-dynamically-added-i2c-devices.patch new file mode 100644 index 0000000000..0541df05b9 --- /dev/null +++ b/queue-5.10/i3c-support-dynamically-added-i2c-devices.patch @@ -0,0 +1,187 @@ +From 9f9c16a0e828c44e3b18f4f0778cbb171d16ac16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jan 2022 17:48:16 +0000 +Subject: i3c: support dynamically added i2c devices + +From: Jamie Iles + +[ Upstream commit 72a4501b5d089772671360a6ec74d5350acf8c2e ] + +I2C devices can be added to the system dynamically through several +sources other than static board info including device tree overlays and +sysfs i2c new_device. + +Add an I2C bus notifier to attach the clients at runtime if they were +not defined in the board info. For DT devices find the LVR in the reg +property, for user-space new_device additions we synthesize a +conservative setting of no spike filters and fast mode only. + +Cc: Alexandre Belloni +Signed-off-by: Jamie Iles +Signed-off-by: Alexandre Belloni +Link: https://lore.kernel.org/r/20220117174816.1963463-3-quic_jiles@quicinc.com +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 128 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 127 insertions(+), 1 deletion(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index e3fffc5015c10..f9f96c4bb9002 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2212,11 +2212,122 @@ static u32 i3c_master_i2c_funcs(struct i2c_adapter *adapter) + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; + } + ++static u8 i3c_master_i2c_get_lvr(struct i2c_client *client) ++{ ++ /* Fall back to no spike filters and FM bus mode. */ ++ u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE; ++ ++ if (client->dev.of_node) { ++ u32 reg[3]; ++ ++ if (!of_property_read_u32_array(client->dev.of_node, "reg", ++ reg, ARRAY_SIZE(reg))) ++ lvr = reg[2]; ++ } ++ ++ return lvr; ++} ++ ++static int i3c_master_i2c_attach(struct i2c_adapter *adap, struct i2c_client *client) ++{ ++ struct i3c_master_controller *master = i2c_adapter_to_i3c_master(adap); ++ enum i3c_addr_slot_status status; ++ struct i2c_dev_desc *i2cdev; ++ int ret; ++ ++ /* Already added by board info? */ ++ if (i3c_master_find_i2c_dev_by_addr(master, client->addr)) ++ return 0; ++ ++ status = i3c_bus_get_addr_slot_status(&master->bus, client->addr); ++ if (status != I3C_ADDR_SLOT_FREE) ++ return -EBUSY; ++ ++ i3c_bus_set_addr_slot_status(&master->bus, client->addr, ++ I3C_ADDR_SLOT_I2C_DEV); ++ ++ i2cdev = i3c_master_alloc_i2c_dev(master, client->addr, ++ i3c_master_i2c_get_lvr(client)); ++ if (IS_ERR(i2cdev)) { ++ ret = PTR_ERR(i2cdev); ++ goto out_clear_status; ++ } ++ ++ ret = i3c_master_attach_i2c_dev(master, i2cdev); ++ if (ret) ++ goto out_free_dev; ++ ++ return 0; ++ ++out_free_dev: ++ i3c_master_free_i2c_dev(i2cdev); ++out_clear_status: ++ i3c_bus_set_addr_slot_status(&master->bus, client->addr, ++ I3C_ADDR_SLOT_FREE); ++ ++ return ret; ++} ++ ++static int i3c_master_i2c_detach(struct i2c_adapter *adap, struct i2c_client *client) ++{ ++ struct i3c_master_controller *master = i2c_adapter_to_i3c_master(adap); ++ struct i2c_dev_desc *dev; ++ ++ dev = i3c_master_find_i2c_dev_by_addr(master, client->addr); ++ if (!dev) ++ return -ENODEV; ++ ++ i3c_master_detach_i2c_dev(dev); ++ i3c_bus_set_addr_slot_status(&master->bus, dev->addr, ++ I3C_ADDR_SLOT_FREE); ++ i3c_master_free_i2c_dev(dev); ++ ++ return 0; ++} ++ + static const struct i2c_algorithm i3c_master_i2c_algo = { + .master_xfer = i3c_master_i2c_adapter_xfer, + .functionality = i3c_master_i2c_funcs, + }; + ++static int i3c_i2c_notifier_call(struct notifier_block *nb, unsigned long action, ++ void *data) ++{ ++ struct i2c_adapter *adap; ++ struct i2c_client *client; ++ struct device *dev = data; ++ struct i3c_master_controller *master; ++ int ret; ++ ++ if (dev->type != &i2c_client_type) ++ return 0; ++ ++ client = to_i2c_client(dev); ++ adap = client->adapter; ++ ++ if (adap->algo != &i3c_master_i2c_algo) ++ return 0; ++ ++ master = i2c_adapter_to_i3c_master(adap); ++ ++ i3c_bus_maintenance_lock(&master->bus); ++ switch (action) { ++ case BUS_NOTIFY_ADD_DEVICE: ++ ret = i3c_master_i2c_attach(adap, client); ++ break; ++ case BUS_NOTIFY_DEL_DEVICE: ++ ret = i3c_master_i2c_detach(adap, client); ++ break; ++ } ++ i3c_bus_maintenance_unlock(&master->bus); ++ ++ return ret; ++} ++ ++static struct notifier_block i2cdev_notifier = { ++ .notifier_call = i3c_i2c_notifier_call, ++}; ++ + static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + { + struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master); +@@ -2747,12 +2858,27 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) + + static int __init i3c_init(void) + { +- return bus_register(&i3c_bus_type); ++ int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); ++ ++ if (res) ++ return res; ++ ++ res = bus_register(&i3c_bus_type); ++ if (res) ++ goto out_unreg_notifier; ++ ++ return 0; ++ ++out_unreg_notifier: ++ bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); ++ ++ return res; + } + subsys_initcall(i3c_init); + + static void __exit i3c_exit(void) + { ++ bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); + idr_destroy(&i3c_bus_idr); + bus_unregister(&i3c_bus_type); + } +-- +2.51.0 + diff --git a/queue-5.10/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch b/queue-5.10/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch new file mode 100644 index 0000000000..c29efa89e4 --- /dev/null +++ b/queue-5.10/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch @@ -0,0 +1,199 @@ +From 35d48eb188f33f90a070b5f7935df03e825a3a71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 12:14:56 +0100 +Subject: iio: imu: st_lsm6dsx: discard samples during filters settling time + +From: Lorenzo Bianconi + +[ Upstream commit db3c490503bee4d0611f9fc17fcd8cfe6fcdbcad ] + +During digital filters settling time the driver is expected to drop +samples since they can be corrupted. Introduce the capability to drop +a given number of samples according to the configured ODR. +Add sample_to_discard for LSM6DSM-like sensors since new generation +devices (e.g. LSM6DSO) support DRDY mask where corrupted samples are +masked in hw with values greather than 0x7ffd so the driver can easily +discard them. +I have not added sample_to_discard support for LSM6DS3 or LSM6DS3H since +I do not have any sample for testing at the moment. + +Reported-by: Philippe De Muyter +Tested-by: Philippe De Muyter +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/21dcd94935c147ef9b1da4984b3da6264ee9609e.1677496295.git.lorenzo@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: c6d702f2b771 ("iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member") +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 ++++ + .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 57 ++++++++++++++++--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 18 ++++++ + 3 files changed, 78 insertions(+), 8 deletions(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index b2202c5ad51e3..3c0ade6ab0d2e 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -119,6 +119,13 @@ struct st_lsm6dsx_odr_table_entry { + int odr_len; + }; + ++struct st_lsm6dsx_samples_to_discard { ++ struct { ++ u32 milli_hz; ++ u16 samples; ++ } val[ST_LSM6DSX_ODR_LIST_SIZE]; ++}; ++ + struct st_lsm6dsx_fs { + u32 gain; + u8 val; +@@ -282,6 +289,7 @@ struct st_lsm6dsx_ext_dev_settings { + * @irq_config: interrupts related registers. + * @drdy_mask: register info for data-ready mask (addr + mask). + * @odr_table: Hw sensors odr table (Hz + val). ++ * @samples_to_discard: Number of samples to discard for filters settling time. + * @fs_table: Hw sensors gain table (gain + val). + * @decimator: List of decimator register info (addr + mask). + * @batch: List of FIFO batching register info (addr + mask). +@@ -315,6 +323,7 @@ struct st_lsm6dsx_settings { + } irq_config; + struct st_lsm6dsx_reg drdy_mask; + struct st_lsm6dsx_odr_table_entry odr_table[2]; ++ struct st_lsm6dsx_samples_to_discard samples_to_discard[2]; + struct st_lsm6dsx_fs_table_entry fs_table[2]; + struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX]; + struct st_lsm6dsx_reg batch[2]; +@@ -336,6 +345,7 @@ enum st_lsm6dsx_fifo_mode { + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. + * @odr: Output data rate of the sensor [Hz]. ++ * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. + * @sip: Number of samples in a given pattern. +@@ -350,6 +360,7 @@ struct st_lsm6dsx_sensor { + u32 gain; + u32 odr; + ++ u16 samples_to_discard; + u16 watermark; + u8 decimator; + u8 sip; +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +index 2ac08b8478968..29ee52c3036ba 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +@@ -459,17 +459,31 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) + } + + if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { +- iio_push_to_buffers_with_timestamp( +- hw->iio_devs[ST_LSM6DSX_ID_GYRO], +- &hw->scan[ST_LSM6DSX_ID_GYRO], +- gyro_sensor->ts_ref + ts); ++ /* ++ * We need to discards gyro samples during ++ * filters settling time ++ */ ++ if (gyro_sensor->samples_to_discard > 0) ++ gyro_sensor->samples_to_discard--; ++ else ++ iio_push_to_buffers_with_timestamp( ++ hw->iio_devs[ST_LSM6DSX_ID_GYRO], ++ &hw->scan[ST_LSM6DSX_ID_GYRO], ++ gyro_sensor->ts_ref + ts); + gyro_sip--; + } + if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { +- iio_push_to_buffers_with_timestamp( +- hw->iio_devs[ST_LSM6DSX_ID_ACC], +- &hw->scan[ST_LSM6DSX_ID_ACC], +- acc_sensor->ts_ref + ts); ++ /* ++ * We need to discards accel samples during ++ * filters settling time ++ */ ++ if (acc_sensor->samples_to_discard > 0) ++ acc_sensor->samples_to_discard--; ++ else ++ iio_push_to_buffers_with_timestamp( ++ hw->iio_devs[ST_LSM6DSX_ID_ACC], ++ &hw->scan[ST_LSM6DSX_ID_ACC], ++ acc_sensor->ts_ref + ts); + acc_sip--; + } + if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { +@@ -659,6 +673,30 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) + return err; + } + ++static void ++st_lsm6dsx_update_samples_to_discard(struct st_lsm6dsx_sensor *sensor) ++{ ++ const struct st_lsm6dsx_samples_to_discard *data; ++ struct st_lsm6dsx_hw *hw = sensor->hw; ++ int i; ++ ++ if (sensor->id != ST_LSM6DSX_ID_GYRO && ++ sensor->id != ST_LSM6DSX_ID_ACC) ++ return; ++ ++ /* check if drdy mask is supported in hw */ ++ if (hw->settings->drdy_mask.addr) ++ return; ++ ++ data = &hw->settings->samples_to_discard[sensor->id]; ++ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) { ++ if (data->val[i].milli_hz == sensor->odr) { ++ sensor->samples_to_discard = data->val[i].samples; ++ return; ++ } ++ } ++} ++ + int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + { + struct st_lsm6dsx_hw *hw = sensor->hw; +@@ -678,6 +716,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + goto out; + } + ++ if (enable) ++ st_lsm6dsx_update_samples_to_discard(sensor); ++ + err = st_lsm6dsx_device_set_enable(sensor, enable); + if (err < 0) + goto out; +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +index ce06ef7d80ee1..9ee1b29cfc27d 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +@@ -618,6 +618,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { + .fs_len = 4, + }, + }, ++ .samples_to_discard = { ++ [ST_LSM6DSX_ID_ACC] = { ++ .val[0] = { 12500, 1 }, ++ .val[1] = { 26000, 1 }, ++ .val[2] = { 52000, 1 }, ++ .val[3] = { 104000, 2 }, ++ .val[4] = { 208000, 2 }, ++ .val[5] = { 416000, 2 }, ++ }, ++ [ST_LSM6DSX_ID_GYRO] = { ++ .val[0] = { 12500, 2 }, ++ .val[1] = { 26000, 5 }, ++ .val[2] = { 52000, 7 }, ++ .val[3] = { 104000, 12 }, ++ .val[4] = { 208000, 20 }, ++ .val[5] = { 416000, 36 }, ++ }, ++ }, + .irq_config = { + .irq1 = { + .addr = 0x0d, +-- +2.51.0 + diff --git a/queue-5.10/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-5.10/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..44e270c372 --- /dev/null +++ b/queue-5.10/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From f64b2280037026b6c5ee5aebb590333ab552852a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 3c0ade6ab0d2e..f6df7ed86b4b9 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -344,7 +344,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-5.10/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch b/queue-5.10/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch new file mode 100644 index 0000000000..2dbd473a6b --- /dev/null +++ b/queue-5.10/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch @@ -0,0 +1,105 @@ +From a71a5715c85745eed5586ea19a838bfd699b7e50 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 13:07:26 +0200 +Subject: iio: imu: st_lsm6dsx: introduce st_lsm6dsx_device_set_enable routine + +From: Lorenzo Bianconi + +[ Upstream commit cd83c5c10036a2a156d725725daf3409832c8a24 ] + +Introduce st_lsm6dsx_device_set_enable utility routine and remove +duplicated code used to enable/disable sensors + +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/e3fbe5d4a3bed41130908669f745f78c8505cf47.1665399959.git.lorenzo@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: c6d702f2b771 ("iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member") +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 +++++++++++ + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 14 +++----------- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 14 ++------------ + 3 files changed, 16 insertions(+), 23 deletions(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 6cf8c3321d6a8..b2202c5ad51e3 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -499,6 +499,17 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, + return &hw->orientation; + } + ++static inline int ++st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) ++{ ++ if (sensor->id == ST_LSM6DSX_ID_EXT0 || ++ sensor->id == ST_LSM6DSX_ID_EXT1 || ++ sensor->id == ST_LSM6DSX_ID_EXT2) ++ return st_lsm6dsx_shub_set_enable(sensor, enable); ++ ++ return st_lsm6dsx_sensor_set_enable(sensor, enable); ++} ++ + static const + struct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_accel_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +index 2e6c634c56c7e..2ac08b8478968 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +@@ -678,17 +678,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + goto out; + } + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) { +- err = st_lsm6dsx_shub_set_enable(sensor, enable); +- if (err < 0) +- goto out; +- } else { +- err = st_lsm6dsx_sensor_set_enable(sensor, enable); +- if (err < 0) +- goto out; +- } ++ err = st_lsm6dsx_device_set_enable(sensor, enable); ++ if (err < 0) ++ goto out; + + err = st_lsm6dsx_set_fifo_odr(sensor, enable); + if (err < 0) +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +index 2c528425b03b4..ce06ef7d80ee1 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +@@ -2450,12 +2450,7 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) + continue; + } + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) +- err = st_lsm6dsx_shub_set_enable(sensor, false); +- else +- err = st_lsm6dsx_sensor_set_enable(sensor, false); ++ err = st_lsm6dsx_device_set_enable(sensor, false); + if (err < 0) + return err; + +@@ -2486,12 +2481,7 @@ static int __maybe_unused st_lsm6dsx_resume(struct device *dev) + if (!(hw->suspend_mask & BIT(sensor->id))) + continue; + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) +- err = st_lsm6dsx_shub_set_enable(sensor, true); +- else +- err = st_lsm6dsx_sensor_set_enable(sensor, true); ++ err = st_lsm6dsx_device_set_enable(sensor, true); + if (err < 0) + return err; + +-- +2.51.0 + diff --git a/queue-5.10/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-5.10/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..4fe9307e1f --- /dev/null +++ b/queue-5.10/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From 8867a7af5095612c75d19d1e8d7e6046c799b991 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 8d69b2e27936a..540c1ec9fe729 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -581,7 +581,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, struct inode *inode, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-5.10/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-5.10/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..a2a11d30ce --- /dev/null +++ b/queue-5.10/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From 39abea1d3f452b042da9eed30f0f90e47d0617e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index bfba1c312a553..4e5386cdb09cd 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -769,6 +769,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index ac2d185c04ef8..9b7c845245274 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -578,8 +578,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -588,6 +591,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-5.10/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-5.10/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..0d66769ee4 --- /dev/null +++ b/queue-5.10/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From dda87a51ff151a8b3dcf08014eb9105e2d3bb0aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 91d9c4d98f39b..af1191a81e29a 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -48,17 +48,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -81,6 +83,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-5.10/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-5.10/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..c14de23fe8 --- /dev/null +++ b/queue-5.10/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From dc1643c7dfbb775b1cecdf1db691410046a97948 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index aa54bfcb0433f..7783cbdb8dc02 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -226,7 +226,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-5.10/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch b/queue-5.10/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch new file mode 100644 index 0000000000..80688f0a57 --- /dev/null +++ b/queue-5.10/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch @@ -0,0 +1,123 @@ +From c094bf21ab9d4f80c3437473ad5385fd8ce6945d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 17:03:41 +0200 +Subject: kmsan: introduce __no_sanitize_memory and __no_kmsan_checks + +From: Alexander Potapenko + +[ Upstream commit 9b448bc25b776daab3215393c3ce6953dd3bb8ad ] + +__no_sanitize_memory is a function attribute that instructs KMSAN to skip +a function during instrumentation. This is needed to e.g. implement the +noinstr functions. + +__no_kmsan_checks is a function attribute that makes KMSAN ignore the +uninitialized values coming from the function's inputs, and initialize the +function's outputs. + +Functions marked with this attribute can't be inlined into functions not +marked with it, and vice versa. This behavior is overridden by +__always_inline. + +__SANITIZE_MEMORY__ is a macro that's defined iff the file is instrumented +with KMSAN. This is not the same as CONFIG_KMSAN, which is defined for +every file. + +Link: https://lkml.kernel.org/r/20220915150417.722975-8-glider@google.com +Signed-off-by: Alexander Potapenko +Reviewed-by: Marco Elver +Cc: Alexander Viro +Cc: Alexei Starovoitov +Cc: Andrey Konovalov +Cc: Andrey Konovalov +Cc: Andy Lutomirski +Cc: Arnd Bergmann +Cc: Borislav Petkov +Cc: Christoph Hellwig +Cc: Christoph Lameter +Cc: David Rientjes +Cc: Dmitry Vyukov +Cc: Eric Biggers +Cc: Eric Biggers +Cc: Eric Dumazet +Cc: Greg Kroah-Hartman +Cc: Herbert Xu +Cc: Ilya Leoshkevich +Cc: Ingo Molnar +Cc: Jens Axboe +Cc: Joonsoo Kim +Cc: Kees Cook +Cc: Mark Rutland +Cc: Matthew Wilcox +Cc: Michael S. Tsirkin +Cc: Pekka Enberg +Cc: Peter Zijlstra +Cc: Petr Mladek +Cc: Stephen Rothwell +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Vasily Gorbik +Cc: Vegard Nossum +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-clang.h | 23 +++++++++++++++++++++++ + include/linux/compiler-gcc.h | 6 ++++++ + 2 files changed, 29 insertions(+) + +diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h +index 383295e21e52b..d9376e327d665 100644 +--- a/include/linux/compiler-clang.h ++++ b/include/linux/compiler-clang.h +@@ -89,6 +89,29 @@ + #define __no_sanitize_undefined + #endif + ++#if __has_feature(memory_sanitizer) ++#define __SANITIZE_MEMORY__ ++/* ++ * Unlike other sanitizers, KMSAN still inserts code into functions marked with ++ * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation ++ * provides the behavior consistent with other __no_sanitize_ attributes, ++ * guaranteeing that __no_sanitize_memory functions remain uninstrumented. ++ */ ++#define __no_sanitize_memory __disable_sanitizer_instrumentation ++ ++/* ++ * The __no_kmsan_checks attribute ensures that a function does not produce ++ * false positive reports by: ++ * - initializing all local variables and memory stores in this function; ++ * - skipping all shadow checks; ++ * - passing initialized arguments to this function's callees. ++ */ ++#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory"))) ++#else ++#define __no_sanitize_memory ++#define __no_kmsan_checks ++#endif ++ + /* + * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together + * with no_sanitize("coverage"). Prior versions of Clang support coverage +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index faf0fd509cb5a..a16d182a3e955 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -148,6 +148,12 @@ + #define __SANITIZE_ADDRESS__ + #endif + ++/* ++ * GCC does not support KMSAN. ++ */ ++#define __no_sanitize_memory ++#define __no_kmsan_checks ++ + /* + * Turn individual warnings and errors on and off locally, depending + * on version. +-- +2.51.0 + diff --git a/queue-5.10/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-5.10/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..5efd62fdb5 --- /dev/null +++ b/queue-5.10/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From b549c0c2202ae15c698e601b90238b56a0d88c39 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index c2cc45e19c4b2..1083c71fe3bb2 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-5.10/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-5.10/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..4a13e50370 --- /dev/null +++ b/queue-5.10/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From 9c32ccbadfadb2dc22cf4bb5641d4caf87f645e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 90372391ce908..b643012ae47f6 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1829,9 +1829,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool raw = false; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1886,6 +1883,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-5.10/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-5.10/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..deb75b4016 --- /dev/null +++ b/queue-5.10/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From 87e02c415860587e1d16d8873a58d31a7d0ee311 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index 28b8581b44dda..b622df9f4b231 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -186,13 +186,14 @@ static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-5.10/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-5.10/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..18767519f1 --- /dev/null +++ b/queue-5.10/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From 861db20ff24ebd940627155dac543e61852acf14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index 6d0af8486269a..4f57766b42496 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -410,6 +410,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.10/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-5.10/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..008aae79c0 --- /dev/null +++ b/queue-5.10/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 946152fae631b1f5af7571e1b32fb8052ec657ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index db734f2831ff0..db89da7b98f1d 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -227,6 +227,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.10/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-5.10/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..c9d374699f --- /dev/null +++ b/queue-5.10/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From e0b486606c275fa5554c5272adc202d6f0501313 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 2924919da991a..e1daed7edc841 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -206,6 +206,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.10/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-5.10/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..dd15776120 --- /dev/null +++ b/queue-5.10/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From 6b56546fa82a9353c101500fc59e7203052c918b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index ee063baed136c..5c39c9c653233 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -562,7 +562,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -578,7 +578,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -604,7 +604,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-5.10/nbd-clean-up-return-value-checking-of-sock_xmit.patch b/queue-5.10/nbd-clean-up-return-value-checking-of-sock_xmit.patch new file mode 100644 index 0000000000..808d83f4d1 --- /dev/null +++ b/queue-5.10/nbd-clean-up-return-value-checking-of-sock_xmit.patch @@ -0,0 +1,85 @@ +From f670e09b0137b9e280d6bf9f0b89fdf7dba6a303 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 17:33:48 +0800 +Subject: nbd: clean up return value checking of sock_xmit() + +From: Yu Kuai + +[ Upstream commit f52c0e08237e7864a44311fc78bc9bf2e045611b ] + +Check if sock_xmit() return 0 is useless because it'll never return +0, comment it and remove such checkings. + +Signed-off-by: Yu Kuai +Reviewed-by: Ming Lei +Reviewed-by: Josef Bacik +Link: https://lore.kernel.org/r/20210916093350.1410403-6-yukuai3@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 9517b82d8d42 ("nbd: defer config put in recv_work") +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 4776009587190..555e87a6d3a6d 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -468,7 +468,8 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, + } + + /* +- * Send or receive packet. ++ * Send or receive packet. Return a positive value on success and ++ * negtive value on failue, and never return 0. + */ + static int sock_xmit(struct nbd_device *nbd, int index, int send, + struct iov_iter *iter, int msg_flags, int *sent) +@@ -594,7 +595,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + result = sock_xmit(nbd, index, 1, &from, + (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); + trace_nbd_header_sent(req, handle); +- if (result <= 0) { ++ if (result < 0) { + if (was_interrupted(result)) { + /* If we havne't sent anything we can just return BUSY, + * however if we have sent something we need to make +@@ -638,7 +639,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + skip = 0; + } + result = sock_xmit(nbd, index, 1, &from, flags, &sent); +- if (result <= 0) { ++ if (result < 0) { + if (was_interrupted(result)) { + /* We've already sent the header, we + * have no choice but to set pending and +@@ -690,7 +691,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + reply.magic = 0; + iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); +- if (result <= 0) { ++ if (result < 0) { + if (!nbd_disconnected(config)) + dev_err(disk_to_dev(nbd->disk), + "Receive control failed (result %d)\n", result); +@@ -751,7 +752,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + rq_for_each_segment(bvec, req, iter) { + iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); +- if (result <= 0) { ++ if (result < 0) { + dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", + result); + /* +@@ -1194,7 +1195,7 @@ static void send_disconnects(struct nbd_device *nbd) + iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); + mutex_lock(&nsock->tx_lock); + ret = sock_xmit(nbd, i, 1, &from, 0, NULL); +- if (ret <= 0) ++ if (ret < 0) + dev_err(disk_to_dev(nbd->disk), + "Send disconnect failed %d\n", ret); + mutex_unlock(&nsock->tx_lock); +-- +2.51.0 + diff --git a/queue-5.10/nbd-defer-config-put-in-recv_work.patch b/queue-5.10/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..c8b652662c --- /dev/null +++ b/queue-5.10/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From 26d660d38323b6cfb5fa1a2b89c21c46182bbd60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 92a94fa568a05..faa3f6c52f5f9 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -817,9 +817,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-5.10/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-5.10/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..a780b5f73d --- /dev/null +++ b/queue-5.10/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From 658b7cb397823f898da9317588820fada483b486 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index faa3f6c52f5f9..649a1e8812652 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2052,12 +2052,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + } + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-5.10/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch b/queue-5.10/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch new file mode 100644 index 0000000000..2d688d7736 --- /dev/null +++ b/queue-5.10/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch @@ -0,0 +1,163 @@ +From 001a7ed4f0c04f28a51e869a189d23012a08ee42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 17:33:49 +0800 +Subject: nbd: partition nbd_read_stat() into nbd_read_reply() and + nbd_handle_reply() + +From: Yu Kuai + +[ Upstream commit 3fe1db626a56cdf259c348404f2c5429e2f065a1 ] + +Prepare to fix uaf in nbd_read_stat(), no functional changes. + +Signed-off-by: Yu Kuai +Reviewed-by: Ming Lei +Reviewed-by: Josef Bacik +Link: https://lore.kernel.org/r/20210916093350.1410403-7-yukuai3@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 9517b82d8d42 ("nbd: defer config put in recv_work") +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 74 +++++++++++++++++++++++++++------------------ + 1 file changed, 44 insertions(+), 30 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 555e87a6d3a6d..92a94fa568a05 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -673,38 +673,45 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + return 0; + } + +-/* NULL returned = something went wrong, inform userspace */ +-static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) ++static int nbd_read_reply(struct nbd_device *nbd, int index, ++ struct nbd_reply *reply) + { +- struct nbd_config *config = nbd->config; +- int result; +- struct nbd_reply reply; +- struct nbd_cmd *cmd; +- struct request *req = NULL; +- u64 handle; +- u16 hwq; +- u32 tag; +- struct kvec iov = {.iov_base = &reply, .iov_len = sizeof(reply)}; ++ struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; + struct iov_iter to; +- int ret = 0; ++ int result; + +- reply.magic = 0; +- iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); ++ reply->magic = 0; ++ iov_iter_kvec(&to, READ, &iov, 1, sizeof(*reply)); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); + if (result < 0) { +- if (!nbd_disconnected(config)) ++ if (!nbd_disconnected(nbd->config)) + dev_err(disk_to_dev(nbd->disk), + "Receive control failed (result %d)\n", result); +- return ERR_PTR(result); ++ return result; + } + +- if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { ++ if (ntohl(reply->magic) != NBD_REPLY_MAGIC) { + dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n", +- (unsigned long)ntohl(reply.magic)); +- return ERR_PTR(-EPROTO); ++ (unsigned long)ntohl(reply->magic)); ++ return -EPROTO; + } + +- memcpy(&handle, reply.handle, sizeof(handle)); ++ return 0; ++} ++ ++/* NULL returned = something went wrong, inform userspace */ ++static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, ++ struct nbd_reply *reply) ++{ ++ int result; ++ struct nbd_cmd *cmd; ++ struct request *req = NULL; ++ u64 handle; ++ u16 hwq; ++ u32 tag; ++ int ret = 0; ++ ++ memcpy(&handle, reply->handle, sizeof(handle)); + tag = nbd_handle_to_tag(handle); + hwq = blk_mq_unique_tag_to_hwq(tag); + if (hwq < nbd->tag_set.nr_hw_queues) +@@ -737,9 +744,9 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + ret = -ENOENT; + goto out; + } +- if (ntohl(reply.error)) { ++ if (ntohl(reply->error)) { + dev_err(disk_to_dev(nbd->disk), "Other side returned error (%d)\n", +- ntohl(reply.error)); ++ ntohl(reply->error)); + cmd->status = BLK_STS_IOERR; + goto out; + } +@@ -748,6 +755,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + if (rq_data_dir(req) != WRITE) { + struct req_iterator iter; + struct bio_vec bvec; ++ struct iov_iter to; + + rq_for_each_segment(bvec, req, iter) { + iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); +@@ -761,7 +769,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + * and let the timeout stuff handle resubmitting + * this request onto another connection. + */ +- if (nbd_disconnected(config)) { ++ if (nbd_disconnected(nbd->config)) { + cmd->status = BLK_STS_IOERR; + goto out; + } +@@ -785,24 +793,30 @@ static void recv_work(struct work_struct *work) + work); + struct nbd_device *nbd = args->nbd; + struct nbd_config *config = nbd->config; ++ struct nbd_sock *nsock; + struct nbd_cmd *cmd; + struct request *rq; + + while (1) { +- cmd = nbd_read_stat(nbd, args->index); +- if (IS_ERR(cmd)) { +- struct nbd_sock *nsock = config->socks[args->index]; ++ struct nbd_reply reply; + +- mutex_lock(&nsock->tx_lock); +- nbd_mark_nsock_dead(nbd, nsock, 1); +- mutex_unlock(&nsock->tx_lock); ++ if (nbd_read_reply(nbd, args->index, &reply)) ++ break; ++ ++ cmd = nbd_handle_reply(nbd, args->index, &reply); ++ if (IS_ERR(cmd)) + break; +- } + + rq = blk_mq_rq_from_pdu(cmd); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); + } ++ ++ nsock = config->socks[args->index]; ++ mutex_lock(&nsock->tx_lock); ++ nbd_mark_nsock_dead(nbd, nsock, 1); ++ mutex_unlock(&nsock->tx_lock); ++ + nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); +-- +2.51.0 + diff --git a/queue-5.10/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-5.10/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..30516e78aa --- /dev/null +++ b/queue-5.10/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From 2e3543d575b3c59810a62b731a235f3b13029e8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 6dabe5eaa3be5..edf9a6e328d22 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1608,7 +1608,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1754,14 +1753,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1834,6 +1833,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1844,13 +1845,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1859,11 +1860,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1938,24 +1939,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-5.10/netfilter-nf_conncount-reduce-unnecessary-gc.patch b/queue-5.10/netfilter-nf_conncount-reduce-unnecessary-gc.patch new file mode 100644 index 0000000000..a690185364 --- /dev/null +++ b/queue-5.10/netfilter-nf_conncount-reduce-unnecessary-gc.patch @@ -0,0 +1,118 @@ +From 482cbd4da0a6b7b88dc87fcc4b5f9ba702b8449e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 May 2022 08:35:59 -0700 +Subject: netfilter: nf_conncount: reduce unnecessary GC + +From: William Tu + +[ Upstream commit d265929930e2ffafc744c0ae05fb70acd53be1ee ] + +Currently nf_conncount can trigger garbage collection (GC) +at multiple places. Each GC process takes a spin_lock_bh +to traverse the nf_conncount_list. We found that when testing +port scanning use two parallel nmap, because the number of +connection increase fast, the nf_conncount_count and its +subsequent call to __nf_conncount_add take too much time, +causing several CPU lockup. This happens when user set the +conntrack limit to +20,000, because the larger the limit, +the longer the list that GC has to traverse. + +The patch mitigate the performance issue by avoiding unnecessary +GC with a timestamp. Whenever nf_conncount has done a GC, +a timestamp is updated, and beforce the next time GC is +triggered, we make sure it's more than a jiffies. +By doin this we can greatly reduce the CPU cycles and +avoid the softirq lockup. + +To reproduce it in OVS, +$ ovs-appctl dpctl/ct-set-limits zone=1,limit=20000 +$ ovs-appctl dpctl/ct-get-limits + +At another machine, runs two nmap +$ nmap -p1- +$ nmap -p1- + +Signed-off-by: William Tu +Co-authored-by: Yifeng Sun +Reported-by: Greg Rose +Suggested-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 69894e5b4c5e ("netfilter: nft_connlimit: update the count if add was skipped") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 1 + + net/netfilter/nf_conncount.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index 9645b47fa7e41..e227d997fc716 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -10,6 +10,7 @@ struct nf_conncount_data; + + struct nf_conncount_list { + spinlock_t list_lock; ++ u32 last_gc; /* jiffies at most recent gc */ + struct list_head head; /* connections with the same filtering key */ + unsigned int count; /* length of list */ + }; +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index a66a27fe7f458..ee808b018e4e1 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -132,6 +132,9 @@ static int __nf_conncount_add(struct net *net, + struct nf_conn *found_ct; + unsigned int collect = 0; + ++ if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) ++ goto add_new_node; ++ + /* check the saved connections */ + list_for_each_entry_safe(conn, conn_n, &list->head, node) { + if (collect > CONNCOUNT_GC_MAX_NODES) +@@ -177,6 +180,7 @@ static int __nf_conncount_add(struct net *net, + nf_ct_put(found_ct); + } + ++add_new_node: + if (WARN_ON_ONCE(list->count > INT_MAX)) + return -EOVERFLOW; + +@@ -190,6 +194,7 @@ static int __nf_conncount_add(struct net *net, + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; ++ list->last_gc = (u32)jiffies; + return 0; + } + +@@ -214,6 +219,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list) + spin_lock_init(&list->list_lock); + INIT_LIST_HEAD(&list->head); + list->count = 0; ++ list->last_gc = (u32)jiffies; + } + EXPORT_SYMBOL_GPL(nf_conncount_list_init); + +@@ -227,6 +233,10 @@ bool nf_conncount_gc_list(struct net *net, + unsigned int collected = 0; + bool ret = false; + ++ /* don't bother if we just did GC */ ++ if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc))) ++ return false; ++ + /* don't bother if other cpu is already doing GC */ + if (!spin_trylock(&list->list_lock)) + return false; +@@ -258,6 +268,7 @@ bool nf_conncount_gc_list(struct net *net, + + if (!list->count) + ret = true; ++ list->last_gc = (u32)jiffies; + spin_unlock(&list->list_lock); + + return ret; +-- +2.51.0 + diff --git a/queue-5.10/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-5.10/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..beddafcbb6 --- /dev/null +++ b/queue-5.10/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,504 @@ +From c2172dcc57b3bfc9a7fae3848f62732117bf39ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 69894e5b4c5e ("netfilter: nft_connlimit: update the count if add was skipped") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index e227d997fc716..115bb7e572f7d 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family + void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index ee808b018e4e1..5fdf451f2322c 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen) +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 332f1b21084f8..35c4698db88dd 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index 46fcac75f7268..0ee0a1cabed3a 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 9e8b3b930f926..2a106d03a2011 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -1152,8 +1152,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -1166,8 +1166,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -1196,8 +1197,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -2046,8 +2046,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-5.10/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch b/queue-5.10/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch new file mode 100644 index 0000000000..56471316bd --- /dev/null +++ b/queue-5.10/netfilter-nft_connlimit-move-stateful-fields-out-of-.patch @@ -0,0 +1,104 @@ +From 1aee8ad86df45e3ed1bb9aee9ac2ec1b77d788c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Jan 2022 17:11:13 +0100 +Subject: netfilter: nft_connlimit: move stateful fields out of expression data + +From: Pablo Neira Ayuso + +[ Upstream commit 37f319f37d9005693dff085bb72852eeebc803ef ] + +In preparation for the rule blob representation. + +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 69894e5b4c5e ("netfilter: nft_connlimit: update the count if add was skipped") +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_connlimit.c | 26 ++++++++++++++++++-------- + 1 file changed, 18 insertions(+), 8 deletions(-) + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 091457e5c260d..332f1b21084f8 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -14,7 +14,7 @@ + #include + + struct nft_connlimit { +- struct nf_conncount_list list; ++ struct nf_conncount_list *list; + u32 limit; + bool invert; + }; +@@ -43,12 +43,12 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + return; + } + +- if (nf_conncount_add(nft_net(pkt), &priv->list, tuple_ptr, zone)) { ++ if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { + regs->verdict.code = NF_DROP; + return; + } + +- count = priv->list.count; ++ count = priv->list->count; + + if ((count > priv->limit) ^ priv->invert) { + regs->verdict.code = NFT_BREAK; +@@ -76,7 +76,11 @@ static int nft_connlimit_do_init(const struct nft_ctx *ctx, + invert = true; + } + +- nf_conncount_list_init(&priv->list); ++ priv->list = kmalloc(sizeof(*priv->list), GFP_KERNEL); ++ if (!priv->list) ++ return -ENOMEM; ++ ++ nf_conncount_list_init(priv->list); + priv->limit = limit; + priv->invert = invert; + +@@ -87,7 +91,8 @@ static void nft_connlimit_do_destroy(const struct nft_ctx *ctx, + struct nft_connlimit *priv) + { + nf_ct_netns_put(ctx->net, ctx->family); +- nf_conncount_cache_free(&priv->list); ++ nf_conncount_cache_free(priv->list); ++ kfree(priv->list); + } + + static int nft_connlimit_do_dump(struct sk_buff *skb, +@@ -200,7 +205,11 @@ static int nft_connlimit_clone(struct nft_expr *dst, const struct nft_expr *src, + struct nft_connlimit *priv_dst = nft_expr_priv(dst); + struct nft_connlimit *priv_src = nft_expr_priv(src); + +- nf_conncount_list_init(&priv_dst->list); ++ priv_dst->list = kmalloc(sizeof(*priv_dst->list), GFP_ATOMIC); ++ if (priv_dst->list) ++ return -ENOMEM; ++ ++ nf_conncount_list_init(priv_dst->list); + priv_dst->limit = priv_src->limit; + priv_dst->invert = priv_src->invert; + +@@ -212,7 +221,8 @@ static void nft_connlimit_destroy_clone(const struct nft_ctx *ctx, + { + struct nft_connlimit *priv = nft_expr_priv(expr); + +- nf_conncount_cache_free(&priv->list); ++ nf_conncount_cache_free(priv->list); ++ kfree(priv->list); + } + + static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr) +@@ -221,7 +231,7 @@ static bool nft_connlimit_gc(struct net *net, const struct nft_expr *expr) + bool ret; + + local_bh_disable(); +- ret = nf_conncount_gc_list(net, &priv->list); ++ ret = nf_conncount_gc_list(net, priv->list); + local_bh_enable(); + + return ret; +-- +2.51.0 + diff --git a/queue-5.10/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-5.10/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..f57231b4b8 --- /dev/null +++ b/queue-5.10/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From d9c62568f60f50e8b4c9191cf31a9278e4a48d15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 5fdf451f2322c..3e8828bdcd1b3 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 35c4698db88dd..698b77a0ba0b4 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-5.10/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-5.10/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..c4f17fc98d --- /dev/null +++ b/queue-5.10/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 527f2afe1f940bc659f5ab1915693dfb5780ad3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index aa9b7ae59a076..e01b141ac7334 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -27,6 +27,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -57,7 +58,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-5.10/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-5.10/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..3c85e630b9 --- /dev/null +++ b/queue-5.10/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From 84977a1831907e2989b9ab73ac7f57a88916f0a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 3cc28afe9815e..6df8b5513bab0 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -100,7 +100,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-5.10/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-5.10/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..40cf66c337 --- /dev/null +++ b/queue-5.10/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From ed38eee1c44af85ad6b6d362e0ef158225fc3fe5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index 9d2f511f13faf..2dfeec79c6718 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -52,7 +52,7 @@ + #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-5.10/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-5.10/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..0a36e609d1 --- /dev/null +++ b/queue-5.10/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 5028c7ca093c6c08dd308098c4d43eed023f7d71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 6245c179ce49f..6844c4652e702 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1382,6 +1382,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-5.10/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-5.10/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..696dee78fd --- /dev/null +++ b/queue-5.10/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From 633869557077bff8598b8a48799ab5649bab96a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 33954835c8231..40e2362096d8c 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -893,11 +893,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + if (ndso == NULL) +-- +2.51.0 + diff --git a/queue-5.10/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-5.10/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..0e1fb84e3d --- /dev/null +++ b/queue-5.10/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From 7cf52375b724bff0422f8a825ee28636c5c69451 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index fb2e81fa62c45..73d1cebddee70 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3515,7 +3515,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-5.10/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-5.10/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..ab7210171c --- /dev/null +++ b/queue-5.10/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From 218d3675f30dbbc5c84d22a796d142dbc2dede91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index bdcb5ede9b631..07bf090420453 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -490,7 +490,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -553,9 +554,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-5.10/pinctrl-single-fix-pin_config_bias_disable-handling.patch b/queue-5.10/pinctrl-single-fix-pin_config_bias_disable-handling.patch new file mode 100644 index 0000000000..43d1fb8519 --- /dev/null +++ b/queue-5.10/pinctrl-single-fix-pin_config_bias_disable-handling.patch @@ -0,0 +1,95 @@ +From 4276fb6334ef4c5f9318016f38034875ba012072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 12:06:34 +0100 +Subject: pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling + +From: Matthijs Kooijman + +[ Upstream commit b5fe46efc147516a908d2d31bf40eb858ab76d51 ] + +The pinctrl-single driver handles pin_config_set by looking up the +requested setting in a DT-defined lookup table, which defines what bits +correspond to each setting. There is no way to add +PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead +code to disable the bias by applying the disable values of both the +pullup and pulldown entries in the table. + +However, this code is inside the table-lookup loop, so it would only +execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, +which can never exist, so this code never runs. + +This commit lifts the offending code out of the loop, so it just +executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, +skippipng the table lookup loop. + +This also introduces a new `param` variable to make the code slightly +more readable. + +This bug seems to have existed when this code was first merged in commit +9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier +versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in +the lookup table, but that was removed, which is probably how this bug +was introduced. + +Signed-off-by: Matthijs Kooijman +Reviewed-by: Haojian Zhuang +Reviewed-by: Tony Lindgren +Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> +Signed-off-by: Linus Walleij +Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable") +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 9485737638b3c..bdcb5ede9b631 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -556,21 +556,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + unsigned offset = 0, shift = 0, i, data, ret; + u32 arg; + int j; ++ enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (j = 0; j < num_configs; j++) { ++ param = pinconf_to_config_param(configs[j]); ++ ++ /* BIAS_DISABLE has no entry in the func->conf table */ ++ if (param == PIN_CONFIG_BIAS_DISABLE) { ++ /* This just disables all bias entries */ ++ pcs_pinconf_clear_bias(pctldev, pin); ++ continue; ++ } ++ + for (i = 0; i < func->nconfs; i++) { +- if (pinconf_to_config_param(configs[j]) +- != func->conf[i].param) ++ if (param != func->conf[i].param) + continue; + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset); + arg = pinconf_to_config_argument(configs[j]); +- switch (func->conf[i].param) { ++ switch (param) { + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_DRIVE_STRENGTH: +@@ -581,9 +590,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + data |= (arg << shift) & func->conf[i].mask; + break; + /* 4 parameters */ +- case PIN_CONFIG_BIAS_DISABLE: +- pcs_pinconf_clear_bias(pctldev, pin); +- break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (arg) { +-- +2.51.0 + diff --git a/queue-5.10/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-5.10/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..bc8059662f --- /dev/null +++ b/queue-5.10/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From 9eaf35dd13c47b4a94c656970026b8b510cdd2c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 6b6fdb7116590..0094ccb4c63c8 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1494,7 +1494,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-5.10/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-5.10/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..8b86544d7e --- /dev/null +++ b/queue-5.10/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From ef3297c62558df4e936f22bc4fb0e89d59791ec2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9d1a7fbcaed42..50b9636945599 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -365,7 +365,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-5.10/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-5.10/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..1b67e12c9d --- /dev/null +++ b/queue-5.10/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From 43479fdf40bb6002518f6b75d9de354491f517d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 18b33f14dfeef..aae655109862c 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-5.10/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-5.10/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..fc014e8ec4 --- /dev/null +++ b/queue-5.10/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From d7f167d61871f39fcb97c89484f3a392c7c3a118 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index ad6df9a2e7c8c..6fed0fc236ff5 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-5.10/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-5.10/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..7cc904aa81 --- /dev/null +++ b/queue-5.10/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From 71169e9252acacfa8fad291d5ba6bb899843e557 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index aec1a963f46e2..0a7819f2200a2 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -35,29 +35,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return container_of(chip, struct bcm2835_pwm, chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -90,6 +67,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -107,8 +87,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + .owner = THIS_MODULE, + }; +-- +2.51.0 + diff --git a/queue-5.10/pwm-bcm2835-support-apply-function-for-atomic-config.patch b/queue-5.10/pwm-bcm2835-support-apply-function-for-atomic-config.patch new file mode 100644 index 0000000000..e3269abbaa --- /dev/null +++ b/queue-5.10/pwm-bcm2835-support-apply-function-for-atomic-config.patch @@ -0,0 +1,141 @@ +From 1d7e75c63dd5548c01c13d43deb14ab18d76fbdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Dec 2020 21:48:25 +0100 +Subject: pwm: bcm2835: Support apply function for atomic configuration +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lino Sanfilippo + +[ Upstream commit 2f81b51d0d02074502ad27424c228ca760823668 ] + +Use the newer .apply function of pwm_ops instead of .config, .enable, +.disable and .set_polarity. This guarantees atomic changes of the pwm +controller configuration. It also reduces the size of the driver. + +Since now period is a 64 bit value, add an extra check to reject periods +that exceed the possible max value for the 32 bit register. + +This has been tested on a Raspberry PI 4. + +Signed-off-by: Lino Sanfilippo +Reviewed-by: Uwe Kleine-König +Signed-off-by: Thierry Reding +Stable-dep-of: cda323dbda76 ("pwm: bcm2835: Make sure the channel is enabled after pwm_request()") +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 69 ++++++++++++++------------------------- + 1 file changed, 24 insertions(+), 45 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 6841dcfe27fc8..aec1a963f46e2 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -58,13 +58,15 @@ static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) + writel(value, pc->base + PWM_CONTROL); + } + +-static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, +- int duty_ns, int period_ns) ++static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, ++ const struct pwm_state *state) + { ++ + struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); + unsigned long rate = clk_get_rate(pc->clk); ++ unsigned long long period; + unsigned long scaler; +- u32 period; ++ u32 val; + + if (!rate) { + dev_err(pc->dev, "failed to get clock rate\n"); +@@ -72,54 +74,34 @@ static int bcm2835_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + } + + scaler = DIV_ROUND_CLOSEST(NSEC_PER_SEC, rate); +- period = DIV_ROUND_CLOSEST(period_ns, scaler); ++ /* set period */ ++ period = DIV_ROUND_CLOSEST_ULL(state->period, scaler); + +- if (period < PERIOD_MIN) ++ /* dont accept a period that is too small or has been truncated */ ++ if ((period < PERIOD_MIN) || (period > U32_MAX)) + return -EINVAL; + +- writel(DIV_ROUND_CLOSEST(duty_ns, scaler), +- pc->base + DUTY(pwm->hwpwm)); + writel(period, pc->base + PERIOD(pwm->hwpwm)); + +- return 0; +-} +- +-static int bcm2835_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm); +- writel(value, pc->base + PWM_CONTROL); ++ /* set duty cycle */ ++ val = DIV_ROUND_CLOSEST_ULL(state->duty_cycle, scaler); ++ writel(val, pc->base + DUTY(pwm->hwpwm)); + +- return 0; +-} ++ /* set polarity */ ++ val = readl(pc->base + PWM_CONTROL); + +-static void bcm2835_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- +-static int bcm2835_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, +- enum pwm_polarity polarity) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); ++ if (state->polarity == PWM_POLARITY_NORMAL) ++ val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ else ++ val |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm); + +- if (polarity == PWM_POLARITY_NORMAL) +- value &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ /* enable/disable */ ++ if (state->enabled) ++ val |= PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm); + else +- value |= PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ val &= ~(PWM_ENABLE << PWM_CONTROL_SHIFT(pwm->hwpwm)); + +- writel(value, pc->base + PWM_CONTROL); ++ writel(val, pc->base + PWM_CONTROL); + + return 0; + } +@@ -127,10 +109,7 @@ static int bcm2835_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm, + static const struct pwm_ops bcm2835_pwm_ops = { + .request = bcm2835_pwm_request, + .free = bcm2835_pwm_free, +- .config = bcm2835_pwm_config, +- .enable = bcm2835_pwm_enable, +- .disable = bcm2835_pwm_disable, +- .set_polarity = bcm2835_set_polarity, ++ .apply = bcm2835_pwm_apply, + .owner = THIS_MODULE, + }; + +-- +2.51.0 + diff --git a/queue-5.10/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-5.10/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..ca7f9cca22 --- /dev/null +++ b/queue-5.10/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From 10a79eaf5affa4baa0444471657b1690f43b552e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index ff3e94779e73c..c3efa06bd1fe7 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-5.10/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-5.10/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..3289a23fc7 --- /dev/null +++ b/queue-5.10/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From 8fc160a59051dbf619a9574ab2ef6b7ba32ad3c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 2b315974f4789..3e6f12f98a890 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1405,7 +1405,7 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-5.10/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-5.10/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..08bed76be0 --- /dev/null +++ b/queue-5.10/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From 862660a83d5bd31cbfcc5874bb4087dd79491862 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index b2d866d606512..7abc839a67c2d 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1495,6 +1495,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1514,11 +1516,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.10/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-5.10/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..9e9f4f8b84 --- /dev/null +++ b/queue-5.10/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 966471551cd48100e62283c3e3648b828dbc27c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 7abc839a67c2d..0e2129be02265 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1810,6 +1810,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1818,6 +1819,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2296,22 +2298,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2331,11 +2337,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-5.10/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-5.10/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..139a34c134 --- /dev/null +++ b/queue-5.10/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From e9294f26486056c05d072456d8fb09612fe8939d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 13e56a23e41ec..a1903b4a7f00a 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -1648,15 +1648,15 @@ static int __init ap_module_init(void) + { + int rc, i; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-5.10/s390-smp-fix-fallback-cpu-detection.patch b/queue-5.10/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..8c01dcc954 --- /dev/null +++ b/queue-5.10/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From d478e0d3a256f8435f0c4c2a0721e40213c34a84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 2e0c3b0a5a58a..253774d155a1f 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -732,6 +732,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-5.10/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-5.10/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..930319cd79 --- /dev/null +++ b/queue-5.10/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From f71be6b7c47df7829c81b2637d2c9290e2f6d0d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index 22302612e032b..3c2a07bf92094 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-5.10/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-5.10/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..1eba11beac --- /dev/null +++ b/queue-5.10/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From c9947aee6e678108d4a04a12e652d76c89e453a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index fa607f2182500..2b074b26db725 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1849,6 +1849,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-5.10/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-5.10/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..2d40a907b9 --- /dev/null +++ b/queue-5.10/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From 18646a7e0a4514a8bd5283428b3f58ecc4c3fd9b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index e6996428c07d2..182a89ecc5428 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2635,7 +2635,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-5.10/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-5.10/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..38c76bcde1 --- /dev/null +++ b/queue-5.10/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 0963022215eab103c24ba85818e1ec953d427f5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 0b6349070824b..b6e09b383fdb8 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -144,6 +144,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-5.10/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-5.10/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..cd6d48679c --- /dev/null +++ b/queue-5.10/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 5ec3970284802be2cf4d88bf1b1a62be2aa5cca6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index e35c444902a71..464753f6e0f26 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 25ad591685..09d31314bf 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -25,3 +25,95 @@ comedi-c6xdigio-fix-invalid-pnp-driver-unregistration.patch comedi-multiq3-sanitize-config-options-in-multiq3_attach.patch comedi-check-device-s-attached-status-in-compat-ioctls.patch staging-rtl8723bs-fix-stack-buffer-overflow-in-onassocreq-ie-parsing.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch +iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +s390-smp-fix-fallback-cpu-detection.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +x86-dumpstack-make-show_trace_log_lvl-static.patch +compiler-gcc.h-define-__sanitize_address__-under-hwa.patch +kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch +x86-kmsan-don-t-instrument-stack-walking-functions.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +i3c-remove-i2c-board-info-from-i2c_dev_desc.patch +i3c-support-dynamically-added-i2c-devices.patch +i3c-allow-of-alias-based-persistent-bus-numbering.patch +i3c-master-inherit-dma-masks-and-parameters-from-par.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +ext4-minor-defrag-code-improvements.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +nbd-clean-up-return-value-checking-of-sock_xmit.patch +nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +clk-renesas-r9a06g032-export-function-to-set-dmamux.patch +soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +pwm-bcm2835-support-apply-function-for-atomic-config.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led_bl-take-led_access-lock-when-required.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ext4-remove-unused-return-value-of-__mb_check_buddy.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +virtio-fix-virtqueue_set_affinity-docs.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +netfilter-nft_connlimit-move-stateful-fields-out-of-.patch +netfilter-nf_conncount-reduce-unnecessary-gc.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +pinctrl-single-fix-pin_config_bias_disable-handling.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch diff --git a/queue-5.10/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-5.10/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..043dfb9123 --- /dev/null +++ b/queue-5.10/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From f2df80d3c573d3e0680b7c2e722f4ff48fea0422 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index cb4801fcf9a8c..b88bd37a6b3da 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3552,8 +3552,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3564,28 +3564,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + if (strcmp(name, "current") != 0) + return -EINVAL; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-5.10/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch b/queue-5.10/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch new file mode 100644 index 0000000000..b37bf52a07 --- /dev/null +++ b/queue-5.10/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch @@ -0,0 +1,85 @@ +From 2b777dc02f2e40c536b1a3663863d429992f4be9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 16:22:54 +0100 +Subject: soc: renesas: r9a06g032-sysctrl: Handle h2mode setting based on USBF + presence + +From: Herve Codina + +[ Upstream commit e9fee814b054e4f6f2faf3d9c1944869fe41c9dd ] + +The CFG_USB[H2MODE] allows to switch the USB configuration. The +configuration supported are: + - One host and one device +or + - Two hosts + +Set CFG_USB[H2MODE] based on the USBF controller (USB device) +availability. + +Signed-off-by: Herve Codina +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230105152257.310642-3-herve.codina@bootlin.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 28 ++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 65cd6ed68923e..b3fd97615fc4c 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -24,6 +24,8 @@ + #include + #include + ++#define R9A06G032_SYSCTRL_USB 0x00 ++#define R9A06G032_SYSCTRL_USB_H2MODE (1<<1) + #define R9A06G032_SYSCTRL_DMAMUX 0xA0 + + struct r9a06g032_gate { +@@ -918,6 +920,29 @@ static void r9a06g032_clocks_del_clk_provider(void *data) + of_clk_del_provider(data); + } + ++static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks) ++{ ++ struct device_node *usbf_np = NULL; ++ u32 usb; ++ ++ while ((usbf_np = of_find_compatible_node(usbf_np, NULL, ++ "renesas,rzn1-usbf"))) { ++ if (of_device_is_available(usbf_np)) ++ break; ++ } ++ ++ usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); ++ if (usbf_np) { ++ /* 1 host and 1 device mode */ ++ usb &= ~R9A06G032_SYSCTRL_USB_H2MODE; ++ of_node_put(usbf_np); ++ } else { ++ /* 2 hosts mode */ ++ usb |= R9A06G032_SYSCTRL_USB_H2MODE; ++ } ++ writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); ++} ++ + static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -947,6 +972,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + clocks->reg = of_iomap(np, 0); + if (WARN_ON(!clocks->reg)) + return -ENOMEM; ++ ++ r9a06g032_init_h2mode(clocks); ++ + for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { + const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; + const char *parent_name = d->source ? +-- +2.51.0 + diff --git a/queue-5.10/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-5.10/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..3d548e791f --- /dev/null +++ b/queue-5.10/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From 2bb271bba4c20c38cefc45c43c7d8b6bd658de34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 2c04fcff0e1c5..723ca72d1bd39 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1229,8 +1229,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-5.10/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-5.10/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..eac6c5a71d --- /dev/null +++ b/queue-5.10/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From 84352bb33e5c88c480b335ea8afc63c8e8730a66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index d99d424c05a7a..50909cc9a0bb2 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -445,9 +445,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-5.10/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch b/queue-5.10/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch new file mode 100644 index 0000000000..afbd157a57 --- /dev/null +++ b/queue-5.10/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch @@ -0,0 +1,45 @@ +From 2fcbb7e04b1a86ce42a0fed5f0795d68970f1ec8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Jun 2025 17:46:55 +0800 +Subject: usb: dwc2: disable platform lowlevel hw resources during shutdown + +From: Jisheng Zhang + +[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ] + +On some SoC platforms, in shutdown stage, most components' power is cut +off, but there's still power supply to the so called always-on +domain, so if the dwc2's regulator is from the always-on domain, we +need to explicitly disable it to save power. + +Disable platform lowlevel hw resources such as phy, clock and +regulators etc. in device shutdown hook to reduce non-necessary power +consumption when the platform enters shutdown stage. + +Signed-off-by: Jisheng Zhang +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index f421650cfa03e..57ef6dcb489b8 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -343,6 +343,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); ++ ++ if (hsotg->ll_hw_enabled) ++ dwc2_lowlevel_hw_disable(hsotg); + } + + /** +-- +2.51.0 + diff --git a/queue-5.10/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-5.10/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..5b924ebe85 --- /dev/null +++ b/queue-5.10/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From daf079ee3d117735ba9df81464733c50a7c5429a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 57ef6dcb489b8..175b4c0886284 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -341,11 +341,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-5.10/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-5.10/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..5bcc2f4ee7 --- /dev/null +++ b/queue-5.10/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From 58b22d2632be8880ce369ffbef7311b7d2036ed9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 175b4c0886284..db667038c8ebc 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -626,9 +626,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -679,6 +683,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-5.10/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-5.10/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..27b5b01a63 --- /dev/null +++ b/queue-5.10/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From 2b06b9900aa940c4f16dd62aa6168e82cc1ea281 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index d64aaff223e79..059ea576c6c1d 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2381,7 +2381,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-5.10/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-5.10/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..dfded6e628 --- /dev/null +++ b/queue-5.10/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 3dce4182dfe55296250fc77ec39161375bff6225 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index d9cbbde8ff59d..a82c6e19572b6 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -38,6 +38,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -619,6 +620,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-5.10/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-5.10/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..7bf42a2154 --- /dev/null +++ b/queue-5.10/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From a46187f2cab5323ff6f4e1c03479ecfb376ace04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index b341dd62aa4da..f971986fa0e9a 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -247,7 +247,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu: the cpu no. + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-5.10/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-5.10/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..f7bff4df15 --- /dev/null +++ b/queue-5.10/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From 4a0623432dc59ddf485d86474908907c1e6646d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index ec308836aad9c..cabeec210f166 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -327,19 +327,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count; +@@ -356,15 +364,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -386,8 +399,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -418,7 +433,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -426,8 +442,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -441,7 +459,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -459,12 +477,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + #ifdef CONFIG_PM_SLEEP +-- +2.51.0 + diff --git a/queue-5.10/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch b/queue-5.10/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch new file mode 100644 index 0000000000..ef14d023b7 --- /dev/null +++ b/queue-5.10/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch @@ -0,0 +1,39 @@ +From 8d142ab06ae1a38f4b662c6ff6689a992d36c9ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Apr 2022 22:53:30 +0800 +Subject: watchdog: wdat_wdt: Stop watchdog when uninstalling module + +From: Liu Xinpeng + +[ Upstream commit 330415ebea81b65842e4cc6d2fd985c1b369e650 ] + +Test shows that wachdog still reboots machine after the module +is removed. Use watchdog_stop_on_unregister to stop the watchdog +on removing. + +Signed-off-by: Liu Xinpeng +eviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/1650984810-6247-4-git-send-email-liuxp11@chinatelecom.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Stable-dep-of: 25c0b472eab8 ("watchdog: wdat_wdt: Fix ACPI table leak in probe function") +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index c60723f5ed99d..ec308836aad9c 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -463,6 +463,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); ++ watchdog_stop_on_unregister(&wdat->wdd); + return devm_watchdog_register_device(dev, &wdat->wdd); + } + +-- +2.51.0 + diff --git a/queue-5.10/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-5.10/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..68240c4fa7 --- /dev/null +++ b/queue-5.10/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From 0b34637fb386d24e7955e2972da80f57a1b5672b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 361fef6e1eeaa..61916e202f20b 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -320,10 +320,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-5.10/wifi-ieee80211-correct-fils-status-codes.patch b/queue-5.10/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..c6d3415696 --- /dev/null +++ b/queue-5.10/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From c241c41f197774296e9c045bd40e81785ae9b924 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 770408b2fdafb..f12357c7ea364 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -2627,8 +2627,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + }; +-- +2.51.0 + diff --git a/queue-5.10/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-5.10/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..cf6f7a8ced --- /dev/null +++ b/queue-5.10/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 8963c76c8b1961743fa104fd645d36cac93ee802 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index 025619cd14e82..acd6743f3827f 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-5.10/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-5.10/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..918e65624a --- /dev/null +++ b/queue-5.10/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From fcc5386622c15d2b209de2ee4c149beb7f361a5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index c9df185dc3f4f..00493a2391179 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-5.10/x86-dumpstack-make-show_trace_log_lvl-static.patch b/queue-5.10/x86-dumpstack-make-show_trace_log_lvl-static.patch new file mode 100644 index 0000000000..db52ab9443 --- /dev/null +++ b/queue-5.10/x86-dumpstack-make-show_trace_log_lvl-static.patch @@ -0,0 +1,52 @@ +From 8cc8ccf2f13f5fd8369a83ee85fd707f06746fb0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Nov 2020 21:39:43 +0800 +Subject: x86/dumpstack: Make show_trace_log_lvl() static + +From: Hui Su + +[ Upstream commit 09a217c10504bcaef911cf2af74e424338efe629 ] + +show_trace_log_lvl() is not used by other compilation units so make it +static and remove the declaration from the header file. + +Signed-off-by: Hui Su +Signed-off-by: Borislav Petkov +Link: https://lkml.kernel.org/r/20201113133943.GA136221@rlk +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + arch/x86/include/asm/stacktrace.h | 3 --- + arch/x86/kernel/dumpstack.c | 2 +- + 2 files changed, 1 insertion(+), 4 deletions(-) + +diff --git a/arch/x86/include/asm/stacktrace.h b/arch/x86/include/asm/stacktrace.h +index 49600643faba8..f248eb2ac2d4a 100644 +--- a/arch/x86/include/asm/stacktrace.h ++++ b/arch/x86/include/asm/stacktrace.h +@@ -88,9 +88,6 @@ get_stack_pointer(struct task_struct *task, struct pt_regs *regs) + return (unsigned long *)task->thread.sp; + } + +-void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl); +- + /* The form of the top of the frame on the stack */ + struct stack_frame { + struct stack_frame *next_frame; +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index cf92191de2b2a..7a1fe0d382ce6 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,7 +183,7 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + } + } + +-void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; +-- +2.51.0 + diff --git a/queue-5.10/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-5.10/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..2a6a5d6728 --- /dev/null +++ b/queue-5.10/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From 648555ee46ae342d69aea7771e7971169390ce55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index df6d3d859ca1b..dc0cd8c1ac137 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -189,8 +189,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -311,6 +311,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-5.10/x86-kmsan-don-t-instrument-stack-walking-functions.patch b/queue-5.10/x86-kmsan-don-t-instrument-stack-walking-functions.patch new file mode 100644 index 0000000000..937dfa91d7 --- /dev/null +++ b/queue-5.10/x86-kmsan-don-t-instrument-stack-walking-functions.patch @@ -0,0 +1,116 @@ +From 57bb4b95298e5c09882abd9929e4e9ce3e154022 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 17:04:13 +0200 +Subject: x86: kmsan: don't instrument stack walking functions + +From: Alexander Potapenko + +[ Upstream commit 37ad4ee8364255c73026a3c343403b5977fa7e79 ] + +Upon function exit, KMSAN marks local variables as uninitialized. Further +function calls may result in the compiler creating the stack frame where +these local variables resided. This results in frame pointers being +marked as uninitialized data, which is normally correct, because they are +not stack-allocated. + +However stack unwinding functions are supposed to read and dereference the +frame pointers, in which case KMSAN might be reporting uses of +uninitialized values. + +To work around that, we mark update_stack_state(), unwind_next_frame() and +show_trace_log_lvl() with __no_kmsan_checks, preventing all KMSAN reports +inside those functions and making them return initialized values. + +Link: https://lkml.kernel.org/r/20220915150417.722975-40-glider@google.com +Signed-off-by: Alexander Potapenko +Cc: Alexander Viro +Cc: Alexei Starovoitov +Cc: Andrey Konovalov +Cc: Andrey Konovalov +Cc: Andy Lutomirski +Cc: Arnd Bergmann +Cc: Borislav Petkov +Cc: Christoph Hellwig +Cc: Christoph Lameter +Cc: David Rientjes +Cc: Dmitry Vyukov +Cc: Eric Biggers +Cc: Eric Biggers +Cc: Eric Dumazet +Cc: Greg Kroah-Hartman +Cc: Herbert Xu +Cc: Ilya Leoshkevich +Cc: Ingo Molnar +Cc: Jens Axboe +Cc: Joonsoo Kim +Cc: Kees Cook +Cc: Marco Elver +Cc: Mark Rutland +Cc: Matthew Wilcox +Cc: Michael S. Tsirkin +Cc: Pekka Enberg +Cc: Peter Zijlstra +Cc: Petr Mladek +Cc: Stephen Rothwell +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Vasily Gorbik +Cc: Vegard Nossum +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 6 ++++++ + arch/x86/kernel/unwind_frame.c | 11 +++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 7a1fe0d382ce6..df6d3d859ca1b 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,6 +183,12 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + } + } + ++/* ++ * This function reads pointers from the stack and dereferences them. The ++ * pointers may not have their KMSAN shadow set up properly, which may result ++ * in false positive reports. Disable instrumentation to avoid those. ++ */ ++__no_kmsan_checks + static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, const char *log_lvl) + { +diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c +index d7c44b257f7f4..8943114f9ebed 100644 +--- a/arch/x86/kernel/unwind_frame.c ++++ b/arch/x86/kernel/unwind_frame.c +@@ -183,6 +183,16 @@ static struct pt_regs *decode_frame_pointer(unsigned long *bp) + } + #endif + ++/* ++ * While walking the stack, KMSAN may stomp on stale locals from other ++ * functions that were marked as uninitialized upon function exit, and ++ * now hold the call frame information for the current function (e.g. the frame ++ * pointer). Because KMSAN does not specifically mark call frames as ++ * initialized, false positive reports are possible. To prevent such reports, ++ * we mark the functions scanning the stack (here and below) with ++ * __no_kmsan_checks. ++ */ ++__no_kmsan_checks + static bool update_stack_state(struct unwind_state *state, + unsigned long *next_bp) + { +@@ -251,6 +261,7 @@ static bool update_stack_state(struct unwind_state *state, + return true; + } + ++__no_kmsan_checks + bool unwind_next_frame(struct unwind_state *state) + { + struct pt_regs *regs; +-- +2.51.0 + diff --git a/queue-5.15/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-5.15/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..c065d2a91b --- /dev/null +++ b/queue-5.15/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 3ab1e3e4bfabe2ae4d034ceca6dd97c518c18a32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 2ac48cda5b201..eae7efae3b5cf 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-5.15/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-5.15/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..f756e0419e --- /dev/null +++ b/queue-5.15/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 017f262b73fde7d7722c533945605eb9e01e72f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 4205c7fdc4cc9..7f0fa58b634a3 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1402,6 +1402,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-5.15/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-5.15/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..c18fe673bd --- /dev/null +++ b/queue-5.15/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From c76da2e3ccd9eb463e61085b81ad5f4a224f4186 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 806ee21651d1f..6f26c9bbe57f0 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -259,17 +259,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_xcvr-add-counter-registers.patch b/queue-5.15/asoc-fsl_xcvr-add-counter-registers.patch new file mode 100644 index 0000000000..662ee8ba21 --- /dev/null +++ b/queue-5.15/asoc-fsl_xcvr-add-counter-registers.patch @@ -0,0 +1,156 @@ +From 4b9b63e6a747d32a7c25f2378e1d9d1e8f019bbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 15:03:47 +0800 +Subject: ASoC: fsl_xcvr: Add Counter registers + +From: Shengjiu Wang + +[ Upstream commit 107d170dc46e14cfa575d1b995107ef2f2e51dfe ] + +These counter registers are part of register list, +add them to complete the register map + +- DMAC counter control registers +- Data path Timestamp counter register +- Data path bit counter register +- Data path bit count timestamp register +- Data path bit read timestamp register + +Signed-off-by: Shengjiu Wang +Link: https://lore.kernel.org/r/1666940627-7611-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 40 ++++++++++++++++++++++++++++++++++++++++ + sound/soc/fsl/fsl_xcvr.h | 21 +++++++++++++++++++++ + 2 files changed, 61 insertions(+) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index d0556c79fdb15..1feb5758245f0 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -933,6 +933,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_TSCR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCTR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCRR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL_SET, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL_CLR, 0x00000000 }, +@@ -943,6 +951,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_TX_CS_DATA_3, 0x00000000 }, + { FSL_XCVR_TX_CS_DATA_4, 0x00000000 }, + { FSL_XCVR_TX_CS_DATA_5, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_SET, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_TSCR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCTR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCRR, 0x00000000 }, + { FSL_XCVR_DEBUG_REG_0, 0x00000000 }, + { FSL_XCVR_DEBUG_REG_1, 0x00000000 }, + }; +@@ -974,6 +990,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_TSCR: ++ case FSL_XCVR_RX_DPTH_BCR: ++ case FSL_XCVR_RX_DPTH_BCTR: ++ case FSL_XCVR_RX_DPTH_BCRR: + case FSL_XCVR_TX_DPTH_CTRL: + case FSL_XCVR_TX_DPTH_CTRL_SET: + case FSL_XCVR_TX_DPTH_CTRL_CLR: +@@ -984,6 +1008,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_TX_CS_DATA_3: + case FSL_XCVR_TX_CS_DATA_4: + case FSL_XCVR_TX_CS_DATA_5: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: ++ case FSL_XCVR_TX_DPTH_TSCR: ++ case FSL_XCVR_TX_DPTH_BCR: ++ case FSL_XCVR_TX_DPTH_BCTR: ++ case FSL_XCVR_TX_DPTH_BCRR: + case FSL_XCVR_DEBUG_REG_0: + case FSL_XCVR_DEBUG_REG_1: + return true; +@@ -1016,6 +1048,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: + case FSL_XCVR_TX_DPTH_CTRL_SET: + case FSL_XCVR_TX_DPTH_CTRL_CLR: + case FSL_XCVR_TX_DPTH_CTRL_TOG: +@@ -1025,6 +1061,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_TX_CS_DATA_3: + case FSL_XCVR_TX_CS_DATA_4: + case FSL_XCVR_TX_CS_DATA_5: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: + return true; + default: + return false; +diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h +index 7f2853c60085e..4769b0fca21de 100644 +--- a/sound/soc/fsl/fsl_xcvr.h ++++ b/sound/soc/fsl/fsl_xcvr.h +@@ -49,6 +49,16 @@ + #define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188 + #define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c + ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG 0x1CC ++ ++#define FSL_XCVR_RX_DPTH_TSCR 0x1D0 ++#define FSL_XCVR_RX_DPTH_BCR 0x1D4 ++#define FSL_XCVR_RX_DPTH_BCTR 0x1D8 ++#define FSL_XCVR_RX_DPTH_BCRR 0x1DC ++ + #define FSL_XCVR_TX_DPTH_CTRL 0x220 /* TX datapath ctrl reg */ + #define FSL_XCVR_TX_DPTH_CTRL_SET 0x224 + #define FSL_XCVR_TX_DPTH_CTRL_CLR 0x228 +@@ -59,6 +69,17 @@ + #define FSL_XCVR_TX_CS_DATA_3 0x23C + #define FSL_XCVR_TX_CS_DATA_4 0x240 + #define FSL_XCVR_TX_CS_DATA_5 0x244 ++ ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL 0x260 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_SET 0x264 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR 0x268 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG 0x26C ++ ++#define FSL_XCVR_TX_DPTH_TSCR 0x270 ++#define FSL_XCVR_TX_DPTH_BCR 0x274 ++#define FSL_XCVR_TX_DPTH_BCTR 0x278 ++#define FSL_XCVR_TX_DPTH_BCRR 0x27C ++ + #define FSL_XCVR_DEBUG_REG_0 0x2E0 + #define FSL_XCVR_DEBUG_REG_1 0x2F0 + +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch b/queue-5.15/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch new file mode 100644 index 0000000000..1a4202ceeb --- /dev/null +++ b/queue-5.15/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch @@ -0,0 +1,316 @@ +From c258c4794393e4d7b6a726438bf85ff3cd82d698 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 10:39:52 +0800 +Subject: ASoC: fsl_xcvr: Add support for i.MX93 platform + +From: Chancel Liu + +[ Upstream commit e240b9329a300af7b7c1eba2ce0abbf19e6c540b ] + +Add compatible string and specific soc data to support XCVR on i.MX93 +platform. XCVR IP on i.MX93 is cut to SPDIF only by removing external +PHY. + +Signed-off-by: Chancel Liu +Acked-by: Shengjiu Wang +Link: https://lore.kernel.org/r/20230104023953.2973362-3-chancel.liu@nxp.com +Signed-off-by: Mark Brown +Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 143 ++++++++++++++++++++++++++------------- + sound/soc/fsl/fsl_xcvr.h | 7 ++ + 2 files changed, 102 insertions(+), 48 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 1feb5758245f0..3fee1aa03363b 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -21,6 +21,7 @@ + + struct fsl_xcvr_soc_data { + const char *fw_name; ++ bool spdif_only; + }; + + struct fsl_xcvr { +@@ -261,6 +262,9 @@ static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx) + u32 i, div = 0, log2; + int ret; + ++ if (xcvr->soc_data->spdif_only) ++ return 0; ++ + for (i = 0; i < ARRAY_SIZE(fsl_xcvr_pll_cfg); i++) { + if (fsl_xcvr_pll_cfg[i].fout % freq == 0) { + div = fsl_xcvr_pll_cfg[i].fout / freq; +@@ -353,6 +357,7 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq) + struct device *dev = &xcvr->pdev->dev; + int ret; + ++ freq = xcvr->soc_data->spdif_only ? freq / 10 : freq; + clk_disable_unprepare(xcvr->phy_clk); + ret = clk_set_rate(xcvr->phy_clk, freq); + if (ret < 0) { +@@ -365,6 +370,8 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq) + return ret; + } + ++ if (xcvr->soc_data->spdif_only) ++ return 0; + /* Release AI interface from reset */ + ret = regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, + FSL_XCVR_PHY_AI_CTRL_AI_RESETN); +@@ -547,10 +554,12 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream, + + xcvr->streams |= BIT(substream->stream); + +- /* Disable XCVR controls if there is stream started */ +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, false); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, false); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, false); ++ if (!xcvr->soc_data->spdif_only) { ++ /* Disable XCVR controls if there is stream started */ ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, false); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, false); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, false); ++ } + + return 0; + } +@@ -567,12 +576,13 @@ static void fsl_xcvr_shutdown(struct snd_pcm_substream *substream, + + /* Enable XCVR controls if there is no stream started */ + if (!xcvr->streams) { +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, true); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, +- (xcvr->mode == FSL_XCVR_MODE_ARC)); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, +- (xcvr->mode == FSL_XCVR_MODE_EARC)); +- ++ if (!xcvr->soc_data->spdif_only) { ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, true); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, ++ (xcvr->mode == FSL_XCVR_MODE_ARC)); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, ++ (xcvr->mode == FSL_XCVR_MODE_EARC)); ++ } + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, + FSL_XCVR_IRQ_EARC_ALL, 0); + if (ret < 0) { +@@ -673,7 +683,10 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd, + dev_err(dai->dev, "Failed to stop DATA_TX: %d\n", ret); + return ret; + } +- fallthrough; ++ if (xcvr->soc_data->spdif_only) ++ break; ++ else ++ fallthrough; + case FSL_XCVR_MODE_EARC: + /* clear ISR_CMDC_TX_EN, W1C */ + ret = regmap_write(xcvr->regmap, +@@ -877,9 +890,13 @@ static int fsl_xcvr_dai_probe(struct snd_soc_dai *dai) + + snd_soc_dai_init_dma_data(dai, &xcvr->dma_prms_tx, &xcvr->dma_prms_rx); + +- snd_soc_add_dai_controls(dai, &fsl_xcvr_mode_kctl, 1); +- snd_soc_add_dai_controls(dai, &fsl_xcvr_arc_mode_kctl, 1); +- snd_soc_add_dai_controls(dai, &fsl_xcvr_earc_capds_kctl, 1); ++ if (xcvr->soc_data->spdif_only) ++ xcvr->mode = FSL_XCVR_MODE_SPDIF; ++ else { ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_mode_kctl, 1); ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_arc_mode_kctl, 1); ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_earc_capds_kctl, 1); ++ } + snd_soc_add_dai_controls(dai, fsl_xcvr_tx_ctls, + ARRAY_SIZE(fsl_xcvr_tx_ctls)); + snd_soc_add_dai_controls(dai, fsl_xcvr_rx_ctls, +@@ -929,10 +946,11 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_ISR_SET, 0x00000000 }, + { FSL_XCVR_ISR_CLR, 0x00000000 }, + { FSL_XCVR_ISR_TOG, 0x00000000 }, +- { FSL_XCVR_RX_DPTH_CTRL, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, ++ { FSL_XCVR_CLK_CTRL, 0x0000018F }, ++ { FSL_XCVR_RX_DPTH_CTRL, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00040CC1 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, +@@ -965,6 +983,12 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + + static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + { ++ struct fsl_xcvr *xcvr = dev_get_drvdata(dev); ++ ++ if (xcvr->soc_data->spdif_only) ++ if ((reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA) || ++ reg > FSL_XCVR_TX_DPTH_BCRR) ++ return false; + switch (reg) { + case FSL_XCVR_VERSION: + case FSL_XCVR_EXT_CTRL: +@@ -990,6 +1014,12 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_CS_DATA_0: ++ case FSL_XCVR_RX_CS_DATA_1: ++ case FSL_XCVR_RX_CS_DATA_2: ++ case FSL_XCVR_RX_CS_DATA_3: ++ case FSL_XCVR_RX_CS_DATA_4: ++ case FSL_XCVR_RX_CS_DATA_5: + case FSL_XCVR_RX_DPTH_CNTR_CTRL: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: +@@ -1026,6 +1056,11 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + + static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + { ++ struct fsl_xcvr *xcvr = dev_get_drvdata(dev); ++ ++ if (xcvr->soc_data->spdif_only) ++ if (reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA) ++ return false; + switch (reg) { + case FSL_XCVR_EXT_CTRL: + case FSL_XCVR_EXT_IER0: +@@ -1102,32 +1137,34 @@ static irqreturn_t irq0_isr(int irq, void *devid) + if (isr & FSL_XCVR_IRQ_NEW_CS) { + dev_dbg(dev, "Received new CS block\n"); + isr_clr |= FSL_XCVR_IRQ_NEW_CS; +- /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ +- regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, +- FSL_XCVR_EXT_CTRL_PAGE_MASK, +- FSL_XCVR_EXT_CTRL_PAGE(8)); +- +- /* Find updated CS buffer */ +- reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_0; +- reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_0; +- memcpy_fromio(&val, reg_ctrl, sizeof(val)); +- if (!val) { +- reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_1; +- reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_1; ++ if (!xcvr->soc_data->spdif_only) { ++ /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ ++ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, ++ FSL_XCVR_EXT_CTRL_PAGE_MASK, ++ FSL_XCVR_EXT_CTRL_PAGE(8)); ++ ++ /* Find updated CS buffer */ ++ reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_0; ++ reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_0; + memcpy_fromio(&val, reg_ctrl, sizeof(val)); +- } ++ if (!val) { ++ reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_1; ++ reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_1; ++ memcpy_fromio(&val, reg_ctrl, sizeof(val)); ++ } + +- if (val) { +- /* copy CS buffer */ +- memcpy_fromio(&xcvr->rx_iec958.status, reg_buff, +- sizeof(xcvr->rx_iec958.status)); +- for (i = 0; i < 6; i++) { +- val = *(u32 *)(xcvr->rx_iec958.status + i*4); +- *(u32 *)(xcvr->rx_iec958.status + i*4) = +- bitrev32(val); ++ if (val) { ++ /* copy CS buffer */ ++ memcpy_fromio(&xcvr->rx_iec958.status, reg_buff, ++ sizeof(xcvr->rx_iec958.status)); ++ for (i = 0; i < 6; i++) { ++ val = *(u32 *)(xcvr->rx_iec958.status + i*4); ++ *(u32 *)(xcvr->rx_iec958.status + i*4) = ++ bitrev32(val); ++ } ++ /* clear CS control register */ ++ memset_io(reg_ctrl, 0, sizeof(val)); + } +- /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); + } + } + if (isr & FSL_XCVR_IRQ_NEW_UD) { +@@ -1167,8 +1204,13 @@ static const struct fsl_xcvr_soc_data fsl_xcvr_imx8mp_data = { + .fw_name = "imx/xcvr/xcvr-imx8mp.bin", + }; + ++static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = { ++ .spdif_only = true, ++}; ++ + static const struct of_device_id fsl_xcvr_dt_ids[] = { + { .compatible = "fsl,imx8mp-xcvr", .data = &fsl_xcvr_imx8mp_data }, ++ { .compatible = "fsl,imx93-xcvr", .data = &fsl_xcvr_imx93_data}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids); +@@ -1228,7 +1270,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev) + return PTR_ERR(xcvr->regmap); + } + +- xcvr->reset = devm_reset_control_get_exclusive(dev, NULL); ++ xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(xcvr->reset)) { + dev_err(dev, "failed to get XCVR reset control\n"); + return PTR_ERR(xcvr->reset); +@@ -1297,12 +1339,14 @@ static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev) + if (ret < 0) + dev_err(dev, "Failed to clear IER0: %d\n", ret); + +- /* Assert M0+ reset */ +- ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, +- FSL_XCVR_EXT_CTRL_CORE_RESET, +- FSL_XCVR_EXT_CTRL_CORE_RESET); +- if (ret < 0) +- dev_err(dev, "Failed to assert M0+ core: %d\n", ret); ++ if (!xcvr->soc_data->spdif_only) { ++ /* Assert M0+ reset */ ++ ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, ++ FSL_XCVR_EXT_CTRL_CORE_RESET, ++ FSL_XCVR_EXT_CTRL_CORE_RESET); ++ if (ret < 0) ++ dev_err(dev, "Failed to assert M0+ core: %d\n", ret); ++ } + + regcache_cache_only(xcvr->regmap, true); + +@@ -1358,6 +1402,9 @@ static __maybe_unused int fsl_xcvr_runtime_resume(struct device *dev) + goto stop_spba_clk; + } + ++ if (xcvr->soc_data->spdif_only) ++ return 0; ++ + ret = reset_control_deassert(xcvr->reset); + if (ret) { + dev_err(dev, "failed to deassert M0+ reset.\n"); +diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h +index 4769b0fca21de..044058fc6aa24 100644 +--- a/sound/soc/fsl/fsl_xcvr.h ++++ b/sound/soc/fsl/fsl_xcvr.h +@@ -49,6 +49,13 @@ + #define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188 + #define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c + ++#define FSL_XCVR_RX_CS_DATA_0 0x190 ++#define FSL_XCVR_RX_CS_DATA_1 0x194 ++#define FSL_XCVR_RX_CS_DATA_2 0x198 ++#define FSL_XCVR_RX_CS_DATA_3 0x19C ++#define FSL_XCVR_RX_CS_DATA_4 0x1A0 ++#define FSL_XCVR_RX_CS_DATA_5 0x1A4 ++ + #define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 + #define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 + #define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 +-- +2.51.0 + diff --git a/queue-5.15/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-5.15/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..dc559fad33 --- /dev/null +++ b/queue-5.15/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From 4f3707cc86964d53de1cd81c9ee8cf37ade74c29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 3fee1aa03363b..8065fa5c95e10 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1163,7 +1163,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } + } +-- +2.51.0 + diff --git a/queue-5.15/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-5.15/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..785bd41211 --- /dev/null +++ b/queue-5.15/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From aa7af752f85228369e19b1d56f9a80baca54d0c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index ebb27daeb1c77..1e737df264d99 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-5.15/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-5.15/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..190ac7cf8d --- /dev/null +++ b/queue-5.15/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 866d634719407ab0bf6e71ed9481452b4ee976a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index d360def24747d..223f078acfd9f 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-5.15/backlight-led_bl-take-led_access-lock-when-required.patch b/queue-5.15/backlight-led_bl-take-led_access-lock-when-required.patch new file mode 100644 index 0000000000..a83f6560ef --- /dev/null +++ b/queue-5.15/backlight-led_bl-take-led_access-lock-when-required.patch @@ -0,0 +1,73 @@ +From 4507d60246199e7fa783283accc042c2a2667c83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jun 2023 17:02:49 +0100 +Subject: backlight: led_bl: Take led_access lock when required + +From: Mans Rullgard + +[ Upstream commit a33677b9211b6c328ad359b072043af94f7c9592 ] + +The led_access lock must be held when calling led_sysfs_enable() and +led_sysfs_disable(). This fixes warnings such as this: + +[ 2.432495] ------------[ cut here ]------------ +[ 2.437316] WARNING: CPU: 0 PID: 22 at drivers/leds/led-core.c:349 led_sysfs_disable+0x54/0x58 +[ 2.446105] Modules linked in: +[ 2.449218] CPU: 0 PID: 22 Comm: kworker/u2:1 Not tainted 6.3.8+ #1 +[ 2.456268] Hardware name: Generic AM3517 (Flattened Device Tree) +[ 2.462402] Workqueue: events_unbound deferred_probe_work_func +[ 2.468353] unwind_backtrace from show_stack+0x10/0x14 +[ 2.473632] show_stack from dump_stack_lvl+0x24/0x2c +[ 2.478759] dump_stack_lvl from __warn+0x9c/0xc4 +[ 2.483551] __warn from warn_slowpath_fmt+0x64/0xc0 +[ 2.488586] warn_slowpath_fmt from led_sysfs_disable+0x54/0x58 +[ 2.494567] led_sysfs_disable from led_bl_probe+0x20c/0x3b0 +[ 2.500305] led_bl_probe from platform_probe+0x5c/0xb8 +[ 2.505615] platform_probe from really_probe+0xc8/0x2a0 +[ 2.510986] really_probe from __driver_probe_device+0x88/0x19c +[ 2.516967] __driver_probe_device from driver_probe_device+0x30/0xcc +[ 2.523498] driver_probe_device from __device_attach_driver+0x94/0xc4 +[ 2.530090] __device_attach_driver from bus_for_each_drv+0x80/0xcc +[ 2.536437] bus_for_each_drv from __device_attach+0xf8/0x19c +[ 2.542236] __device_attach from bus_probe_device+0x8c/0x90 +[ 2.547973] bus_probe_device from deferred_probe_work_func+0x80/0xb0 +[ 2.554504] deferred_probe_work_func from process_one_work+0x228/0x4c0 +[ 2.561187] process_one_work from worker_thread+0x1fc/0x4d0 +[ 2.566925] worker_thread from kthread+0xb4/0xd0 +[ 2.571685] kthread from ret_from_fork+0x14/0x2c +[ 2.576446] Exception stack(0xd0079fb0 to 0xd0079ff8) +[ 2.581573] 9fa0: 00000000 00000000 00000000 00000000 +[ 2.589813] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 2.598052] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 +[ 2.604888] ---[ end trace 0000000000000000 ]--- + +Signed-off-by: Mans Rullgard +Reviewed-by: Daniel Thompson +Link: https://lore.kernel.org/r/20230619160249.10414-1-mans@mansr.com +Signed-off-by: Lee Jones +Stable-dep-of: 9341d6698f4c ("backlight: led-bl: Add devlink to supplier LEDs") +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 589dae9ebb638..d360def24747d 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,8 +209,11 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + +- for (i = 0; i < priv->nb_leds; i++) ++ for (i = 0; i < priv->nb_leds; i++) { ++ mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); ++ mutex_unlock(&priv->leds[i]->led_access); ++ } + + backlight_update_status(priv->bl_dev); + +-- +2.51.0 + diff --git a/queue-5.15/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-5.15/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..81695fa7f8 --- /dev/null +++ b/queue-5.15/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From ef11c0bbc39029aae86fdf7bed1c1911ac8fa88d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-5.15/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch b/queue-5.15/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch new file mode 100644 index 0000000000..7f93fd7628 --- /dev/null +++ b/queue-5.15/clk-renesas-r9a06g032-export-function-to-set-dmamux.patch @@ -0,0 +1,111 @@ +From 03cbaaa923499a558cc771f966367d16709760a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Apr 2022 11:56:48 +0200 +Subject: clk: renesas: r9a06g032: Export function to set dmamux + +From: Miquel Raynal + +[ Upstream commit 885525c1e7e27ea6207d648a8db20dfbbd9e4238 ] + +The dmamux register is located within the system controller. + +Without syscon, we need an extra helper in order to give write access to +this register to a dmamux driver. + +Signed-off-by: Miquel Raynal +Acked-by: Stephen Boyd +Reviewed-by: Geert Uytterhoeven +Acked-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20220427095653.91804-5-miquel.raynal@bootlin.com +Signed-off-by: Vinod Koul +Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 35 ++++++++++++++++++- + include/linux/soc/renesas/r9a06g032-sysctrl.h | 11 ++++++ + 2 files changed, 45 insertions(+), 1 deletion(-) + create mode 100644 include/linux/soc/renesas/r9a06g032-sysctrl.h + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 3e43ae8480ddf..9f42d46ce6192 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -20,9 +20,12 @@ + #include + #include + #include ++#include + #include + #include + ++#define R9A06G032_SYSCTRL_DMAMUX 0xA0 ++ + struct r9a06g032_gate { + u16 gate, reset, ready, midle, + scon, mirack, mistat; +@@ -315,6 +318,30 @@ struct r9a06g032_priv { + void __iomem *reg; + }; + ++static struct r9a06g032_priv *sysctrl_priv; ++ ++/* Exported helper to access the DMAMUX register */ ++int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) ++{ ++ unsigned long flags; ++ u32 dmamux; ++ ++ if (!sysctrl_priv) ++ return -EPROBE_DEFER; ++ ++ spin_lock_irqsave(&sysctrl_priv->lock, flags); ++ ++ dmamux = readl(sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); ++ dmamux &= ~mask; ++ dmamux |= val & mask; ++ writel(dmamux, sysctrl_priv->reg + R9A06G032_SYSCTRL_DMAMUX); ++ ++ spin_unlock_irqrestore(&sysctrl_priv->lock, flags); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(r9a06g032_sysctrl_set_dmamux); ++ + /* register/bit pairs are encoded as an uint16_t */ + static void + clk_rdesc_set(struct r9a06g032_priv *clocks, +@@ -962,7 +989,13 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (error) + return error; + +- return r9a06g032_add_clk_domain(dev); ++ error = r9a06g032_add_clk_domain(dev); ++ if (error) ++ return error; ++ ++ sysctrl_priv = clocks; ++ ++ return 0; + } + + static const struct of_device_id r9a06g032_match[] = { +diff --git a/include/linux/soc/renesas/r9a06g032-sysctrl.h b/include/linux/soc/renesas/r9a06g032-sysctrl.h +new file mode 100644 +index 0000000000000..066dfb15cbddd +--- /dev/null ++++ b/include/linux/soc/renesas/r9a06g032-sysctrl.h +@@ -0,0 +1,11 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#ifndef __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ ++#define __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ ++ ++#ifdef CONFIG_CLK_R9A06G032 ++int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val); ++#else ++static inline int r9a06g032_sysctrl_set_dmamux(u32 mask, u32 val) { return -ENODEV; } ++#endif ++ ++#endif /* __LINUX_SOC_RENESAS_R9A06G032_SYSCTRL_H__ */ +-- +2.51.0 + diff --git a/queue-5.15/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-5.15/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..691fced54b --- /dev/null +++ b/queue-5.15/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 320095778cbcdbe31f82c86f862a77e639872922 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index e46280059db79..7ee8443a38041 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -970,9 +970,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-5.15/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch b/queue-5.15/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch new file mode 100644 index 0000000000..e613e5c562 --- /dev/null +++ b/queue-5.15/compiler-gcc.h-define-__sanitize_address__-under-hwa.patch @@ -0,0 +1,80 @@ +From e6b270d9d4c01c2d3f5d99946c5fa3e49d48cc7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Oct 2021 13:00:39 -0700 +Subject: compiler-gcc.h: Define __SANITIZE_ADDRESS__ under hwaddress sanitizer + +From: Kees Cook + +[ Upstream commit 9a48e7564ac83fb0f1d5b0eac5fe8a7af62da398 ] + +When Clang is using the hwaddress sanitizer, it sets __SANITIZE_ADDRESS__ +explicitly: + + #if __has_feature(address_sanitizer) || __has_feature(hwaddress_sanitizer) + /* Emulate GCC's __SANITIZE_ADDRESS__ flag */ + #define __SANITIZE_ADDRESS__ + #endif + +Once hwaddress sanitizer was added to GCC, however, a separate define +was created, __SANITIZE_HWADDRESS__. The kernel is expecting to find +__SANITIZE_ADDRESS__ in either case, though, and the existing string +macros break on supported architectures: + + #if (defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)) && \ + !defined(__SANITIZE_ADDRESS__) + +where as other architectures (like arm32) have no idea about hwaddress +sanitizer and just check for __SANITIZE_ADDRESS__: + + #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) + +This would lead to compiler foritfy self-test warnings when building +with CONFIG_KASAN_SW_TAGS=y: + +warning: unsafe memmove() usage lacked '__read_overflow2' symbol in lib/test_fortify/read_overflow2-memmove.c +warning: unsafe memcpy() usage lacked '__write_overflow' symbol in lib/test_fortify/write_overflow-memcpy.c +... + +Sort this out by also defining __SANITIZE_ADDRESS__ in GCC under the +hwaddress sanitizer. + +Suggested-by: Arnd Bergmann +Cc: Nick Desaulniers +Cc: Andrew Morton +Cc: Will Deacon +Cc: Arvind Sankar +Cc: Masahiro Yamada +Cc: llvm@lists.linux.dev +Signed-off-by: Kees Cook +Reviewed-by: Nathan Chancellor +Acked-by: Miguel Ojeda +Reviewed-by: Marco Elver +Link: https://lore.kernel.org/r/20211020200039.170424-1-keescook@chromium.org +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-gcc.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index b9d5f9c373a09..06c1cf2ab0244 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -123,6 +123,14 @@ + #define __no_sanitize_coverage + #endif + ++/* ++ * Treat __SANITIZE_HWADDRESS__ the same as __SANITIZE_ADDRESS__ in the kernel, ++ * matching the defines used by Clang. ++ */ ++#ifdef __SANITIZE_HWADDRESS__ ++#define __SANITIZE_ADDRESS__ ++#endif ++ + /* + * Turn individual warnings and errors on and off locally, depending + * on version. +-- +2.51.0 + diff --git a/queue-5.15/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-5.15/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..9c8247de2a --- /dev/null +++ b/queue-5.15/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From 55361160b172e1c63ccca4d187cb6631f397c332 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 7cc854da81988..ce03a53fea7ad 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -406,10 +406,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -830,11 +844,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-5.15/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch b/queue-5.15/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch new file mode 100644 index 0000000000..1d3bf3a8be --- /dev/null +++ b/queue-5.15/coresight-etm4x-add-isb-before-reading-the-trcstatr.patch @@ -0,0 +1,197 @@ +From 9a0cee8a6661eb4689937630624f86c91c77bb6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Jan 2025 17:04:20 +0800 +Subject: coresight-etm4x: add isb() before reading the TRCSTATR + +From: Yuanfang Zhang + +[ Upstream commit 4ff6039ffb79a4a8a44b63810a8a2f2b43264856 ] + +As recommended by section 4.3.7 ("Synchronization when using system +instructions to progrom the trace unit") of ARM IHI 0064H.b, the +self-hosted trace analyzer must perform a Context synchronization +event between writing to the TRCPRGCTLR and reading the TRCSTATR. +Additionally, add an ISB between the each read of TRCSTATR on +coresight_timeout() when using system instructions to program the +trace unit. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Signed-off-by: Yuanfang Zhang +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250116-etm_sync-v4-1-39f2b05e9514@quicinc.com +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-core.c | 20 ++++++-- + .../coresight/coresight-etm4x-core.c | 48 +++++++++++++++++-- + include/linux/coresight.h | 4 ++ + 3 files changed, 62 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c +index f6989a74fec94..1d8bad32c5ad5 100644 +--- a/drivers/hwtracing/coresight/coresight-core.c ++++ b/drivers/hwtracing/coresight/coresight-core.c +@@ -1454,18 +1454,20 @@ static void coresight_remove_conns(struct coresight_device *csdev) + } + + /** +- * coresight_timeout - loop until a bit has changed to a specific register +- * state. ++ * coresight_timeout_action - loop until a bit has changed to a specific register ++ * state, with a callback after every trial. + * @csa: coresight device access for the device + * @offset: Offset of the register from the base of the device. + * @position: the position of the bit of interest. + * @value: the value the bit should have. ++ * @cb: Call back after each trial. + * + * Return: 0 as soon as the bit has taken the desired state or -EAGAIN if + * TIMEOUT_US has elapsed, which ever happens first. + */ +-int coresight_timeout(struct csdev_access *csa, u32 offset, +- int position, int value) ++int coresight_timeout_action(struct csdev_access *csa, u32 offset, ++ int position, int value, ++ coresight_timeout_cb_t cb) + { + int i; + u32 val; +@@ -1481,7 +1483,8 @@ int coresight_timeout(struct csdev_access *csa, u32 offset, + if (!(val & BIT(position))) + return 0; + } +- ++ if (cb) ++ cb(csa, offset, position, value); + /* + * Delay is arbitrary - the specification doesn't say how long + * we are expected to wait. Extra check required to make sure +@@ -1493,6 +1496,13 @@ int coresight_timeout(struct csdev_access *csa, u32 offset, + + return -EAGAIN; + } ++EXPORT_SYMBOL_GPL(coresight_timeout_action); ++ ++int coresight_timeout(struct csdev_access *csa, u32 offset, ++ int position, int value) ++{ ++ return coresight_timeout_action(csa, offset, position, value, NULL); ++} + EXPORT_SYMBOL_GPL(coresight_timeout); + + u32 coresight_relaxed_read32(struct coresight_device *csdev, u32 offset) +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 54e5be46973a3..0b7aceb96d753 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -369,6 +369,29 @@ static void etm4_check_arch_features(struct etmv4_drvdata *drvdata, + } + #endif /* CONFIG_ETM4X_IMPDEF_FEATURE */ + ++static void etm4x_sys_ins_barrier(struct csdev_access *csa, u32 offset, int pos, int val) ++{ ++ if (!csa->io_mem) ++ isb(); ++} ++ ++/* ++ * etm4x_wait_status: Poll for TRCSTATR. == . While using system ++ * instruction to access the trace unit, each access must be separated by a ++ * synchronization barrier. See ARM IHI0064H.b section "4.3.7 Synchronization of ++ * register updates", for system instructions section, in "Notes": ++ * ++ * "In particular, whenever disabling or enabling the trace unit, a poll of ++ * TRCSTATR needs explicit synchronization between each read of TRCSTATR" ++ */ ++static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) ++{ ++ if (!csa->io_mem) ++ return coresight_timeout_action(csa, TRCSTATR, pos, val, ++ etm4x_sys_ins_barrier); ++ return coresight_timeout(csa, TRCSTATR, pos, val); ++} ++ + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + { + int i, rc; +@@ -400,7 +423,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + isb(); + + /* wait for TRCSTATR.IDLE to go up */ +- if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + if (drvdata->nr_pe) +@@ -493,7 +516,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + isb(); + + /* wait for TRCSTATR.IDLE to go back down to '0' */ +- if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 0)) ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + +@@ -818,10 +841,25 @@ static void etm4_disable_hw(void *info) + tsb_csync(); + etm4x_relaxed_write32(csa, control, TRCPRGCTLR); + ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* wait for TRCSTATR.PMSTABLE to go to '1' */ +- if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1)) ++ if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) + dev_err(etm_dev, + "timeout while waiting for PM stable Trace Status\n"); ++ /* ++ * As recommended by section 4.3.7 (Synchronization of register updates) ++ * of ARM IHI 0064H.b. ++ */ ++ isb(); ++ + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { + config->ss_status[i] = +@@ -1592,7 +1630,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + etm4_os_lock(drvdata); + + /* wait for TRCSTATR.PMSTABLE to go up */ +- if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for PM Stable Status\n"); + etm4_os_unlock(drvdata); +@@ -1683,7 +1721,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (coresight_timeout(csa, TRCSTATR, TRCSTATR_IDLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index 93a2922b76534..c0a0db99a6896 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -484,6 +484,10 @@ extern int coresight_enable(struct coresight_device *csdev); + extern void coresight_disable(struct coresight_device *csdev); + extern int coresight_timeout(struct csdev_access *csa, u32 offset, + int position, int value); ++typedef void (*coresight_timeout_cb_t) (struct csdev_access *, u32, int, int); ++extern int coresight_timeout_action(struct csdev_access *csa, u32 offset, ++ int position, int value, ++ coresight_timeout_cb_t cb); + + extern int coresight_claim_device(struct coresight_device *csdev); + extern int coresight_claim_device_unlocked(struct coresight_device *csdev); +-- +2.51.0 + diff --git a/queue-5.15/coresight-etm4x-extract-the-trace-unit-controlling.patch b/queue-5.15/coresight-etm4x-extract-the-trace-unit-controlling.patch new file mode 100644 index 0000000000..aa2fb7b723 --- /dev/null +++ b/queue-5.15/coresight-etm4x-extract-the-trace-unit-controlling.patch @@ -0,0 +1,171 @@ +From e65c379904dfc7d906c269451d49ae62097f6650 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 19:07:02 +0100 +Subject: coresight: etm4x: Extract the trace unit controlling + +From: Leo Yan + +[ Upstream commit 40f682ae5086366d51e29e66eb8a344501245d0d ] + +The trace unit is controlled in the ETM hardware enabling and disabling. +The sequential changes for support AUX pause and resume will reuse the +same operations. + +Extract the operations in the etm4_{enable|disable}_trace_unit() +functions. A minor improvement in etm4_enable_trace_unit() is for +returning the timeout error to callers. + +Signed-off-by: Leo Yan +Reviewed-by: Mike Leach +Reviewed-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250401180708.385396-2-leo.yan@arm.com +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 103 +++++++++++------- + 1 file changed, 62 insertions(+), 41 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 0b7aceb96d753..7cc854da81988 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -392,6 +392,44 @@ static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) + return coresight_timeout(csa, TRCSTATR, pos, val); + } + ++static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) ++{ ++ struct coresight_device *csdev = drvdata->csdev; ++ struct device *etm_dev = &csdev->dev; ++ struct csdev_access *csa = &csdev->access; ++ ++ /* ++ * ETE mandates that the TRCRSR is written to before ++ * enabling it. ++ */ ++ if (etm4x_is_ete(drvdata)) ++ etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); ++ ++ etm4x_allow_trace(drvdata); ++ /* Enable the trace unit */ ++ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); ++ ++ /* Synchronize the register updates for sysreg access */ ++ if (!csa->io_mem) ++ isb(); ++ ++ /* wait for TRCSTATR.IDLE to go back down to '0' */ ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) { ++ dev_err(etm_dev, ++ "timeout while waiting for Idle Trace Status\n"); ++ return -ETIME; ++ } ++ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using the ++ * memory-mapped interface") of ARM IHI 0064D ++ */ ++ dsb(sy); ++ isb(); ++ ++ return 0; ++} ++ + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + { + int i, rc; +@@ -500,33 +538,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); + } + +- /* +- * ETE mandates that the TRCRSR is written to before +- * enabling it. +- */ +- if (etm4x_is_ete(drvdata)) +- etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); +- +- etm4x_allow_trace(drvdata); +- /* Enable the trace unit */ +- etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); +- +- /* Synchronize the register updates for sysreg access */ +- if (!csa->io_mem) +- isb(); +- +- /* wait for TRCSTATR.IDLE to go back down to '0' */ +- if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) +- dev_err(etm_dev, +- "timeout while waiting for Idle Trace Status\n"); +- +- /* +- * As recommended by section 4.3.7 ("Synchronization when using the +- * memory-mapped interface") of ARM IHI 0064D +- */ +- dsb(sy); +- isb(); +- ++ rc = etm4_enable_trace_unit(drvdata); + done: + etm4_cs_lock(drvdata, csa); + +@@ -800,25 +812,12 @@ static int etm4_enable(struct coresight_device *csdev, + return ret; + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; +- struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct device *etm_dev = &csdev->dev; + struct csdev_access *csa = &csdev->access; +- int i; +- +- etm4_cs_unlock(drvdata, csa); +- etm4_disable_arch_specific(drvdata); +- +- if (!drvdata->skip_power_up) { +- /* power can be removed from the trace unit now */ +- control = etm4x_relaxed_read32(csa, TRCPDCR); +- control &= ~TRCPDCR_PU; +- etm4x_relaxed_write32(csa, control, TRCPDCR); +- } + + control = etm4x_relaxed_read32(csa, TRCPRGCTLR); + +@@ -859,6 +858,28 @@ static void etm4_disable_hw(void *info) + * of ARM IHI 0064H.b. + */ + isb(); ++} ++ ++static void etm4_disable_hw(void *info) ++{ ++ u32 control; ++ struct etmv4_drvdata *drvdata = info; ++ struct etmv4_config *config = &drvdata->config; ++ struct coresight_device *csdev = drvdata->csdev; ++ struct csdev_access *csa = &csdev->access; ++ int i; ++ ++ etm4_cs_unlock(drvdata, csa); ++ etm4_disable_arch_specific(drvdata); ++ ++ if (!drvdata->skip_power_up) { ++ /* power can be removed from the trace unit now */ ++ control = etm4x_relaxed_read32(csa, TRCPDCR); ++ control &= ~TRCPDCR_PU; ++ etm4x_relaxed_write32(csa, control, TRCPDCR); ++ } ++ ++ etm4_disable_trace_unit(drvdata); + + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { +-- +2.51.0 + diff --git a/queue-5.15/coresight-etm4x-save-restore-trfcr_el1.patch b/queue-5.15/coresight-etm4x-save-restore-trfcr_el1.patch new file mode 100644 index 0000000000..79aff56a18 --- /dev/null +++ b/queue-5.15/coresight-etm4x-save-restore-trfcr_el1.patch @@ -0,0 +1,184 @@ +From c162793ea00d5f2f24cbc1378f924ec03c4512a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Sep 2021 11:26:32 +0100 +Subject: coresight: etm4x: Save restore TRFCR_EL1 + +From: Suzuki K Poulose + +[ Upstream commit 937d3f58cacf377cab7c32e475e1ffa91d611dce ] + +When the CPU enters a low power mode, the TRFCR_EL1 contents could be +reset. Thus we need to save/restore the TRFCR_EL1 along with the ETM4x +registers to allow the tracing. + +The TRFCR related helpers are in a new header file, as we need to use +them for TRBE in the later patches. + +Cc: Mathieu Poirier +Cc: Anshuman Khandual +Cc: Mike Leach +Cc: Leo Yan +Reviewed-by: Anshuman Khandual +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20210914102641.1852544-2-suzuki.poulose@arm.com +[Fixed cosmetic details] +Signed-off-by: Mathieu Poirier +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 43 +++++++++++++------ + drivers/hwtracing/coresight/coresight-etm4x.h | 2 + + .../coresight/coresight-self-hosted-trace.h | 24 +++++++++++ + 3 files changed, 57 insertions(+), 12 deletions(-) + create mode 100644 drivers/hwtracing/coresight/coresight-self-hosted-trace.h + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 84734c7c19158..d124931ee2be5 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -40,6 +40,7 @@ + #include "coresight-etm4x.h" + #include "coresight-etm-perf.h" + #include "coresight-etm4x-cfg.h" ++#include "coresight-self-hosted-trace.h" + #include "coresight-syscfg.h" + + static int boot_enable; +@@ -1009,7 +1010,7 @@ static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) + if (is_kernel_in_hyp_mode()) + trfcr |= TRFCR_EL2_CX; + +- write_sysreg_s(trfcr, SYS_TRFCR_EL1); ++ write_trfcr(trfcr); + } + + static void etm4_init_arch_data(void *info) +@@ -1534,7 +1535,7 @@ static void etm4_init_trace_id(struct etmv4_drvdata *drvdata) + drvdata->trcid = coresight_get_trace_id(drvdata->cpu); + } + +-static int etm4_cpu_save(struct etmv4_drvdata *drvdata) ++static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + { + int i, ret = 0; + struct etmv4_save_state *state; +@@ -1674,7 +1675,23 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata) + return ret; + } + +-static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) ++static int etm4_cpu_save(struct etmv4_drvdata *drvdata) ++{ ++ int ret = 0; ++ ++ /* Save the TRFCR irrespective of whether the ETM is ON */ ++ if (drvdata->trfc) ++ drvdata->save_trfcr = read_trfcr(); ++ /* ++ * Save and restore the ETM Trace registers only if ++ * the ETM is active. ++ */ ++ if (local_read(&drvdata->mode) && drvdata->save_state) ++ ret = __etm4_cpu_save(drvdata); ++ return ret; ++} ++ ++static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + { + int i; + struct etmv4_save_state *state = drvdata->save_state; +@@ -1773,6 +1790,14 @@ static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) + etm4_cs_lock(drvdata, csa); + } + ++static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) ++{ ++ if (drvdata->trfc) ++ write_trfcr(drvdata->save_trfcr); ++ if (drvdata->state_needs_restore) ++ __etm4_cpu_restore(drvdata); ++} ++ + static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, + void *v) + { +@@ -1784,23 +1809,17 @@ static int etm4_cpu_pm_notify(struct notifier_block *nb, unsigned long cmd, + + drvdata = etmdrvdata[cpu]; + +- if (!drvdata->save_state) +- return NOTIFY_OK; +- + if (WARN_ON_ONCE(drvdata->cpu != cpu)) + return NOTIFY_BAD; + + switch (cmd) { + case CPU_PM_ENTER: +- /* save the state if self-hosted coresight is in use */ +- if (local_read(&drvdata->mode)) +- if (etm4_cpu_save(drvdata)) +- return NOTIFY_BAD; ++ if (etm4_cpu_save(drvdata)) ++ return NOTIFY_BAD; + break; + case CPU_PM_EXIT: + case CPU_PM_ENTER_FAILED: +- if (drvdata->state_needs_restore) +- etm4_cpu_restore(drvdata); ++ etm4_cpu_restore(drvdata); + break; + default: + return NOTIFY_DONE; +diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h +index 3ab528c6b91f1..74f1ba8ed148d 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x.h ++++ b/drivers/hwtracing/coresight/coresight-etm4x.h +@@ -901,6 +901,7 @@ struct etmv4_save_state { + * @lpoverride: If the implementation can support low-power state over. + * @trfc: If the implementation supports Arm v8.4 trace filter controls. + * @config: structure holding configuration parameters. ++ * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. + * @save_state: State to be preserved across power loss + * @state_needs_restore: True when there is context to restore after PM exit + * @skip_power_up: Indicates if an implementation can skip powering up +@@ -954,6 +955,7 @@ struct etmv4_drvdata { + bool lpoverride; + bool trfc; + struct etmv4_config config; ++ u64 save_trfcr; + struct etmv4_save_state *save_state; + bool state_needs_restore; + bool skip_power_up; +diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h +new file mode 100644 +index 0000000000000..303d71911870f +--- /dev/null ++++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Arm v8 Self-Hosted trace support. ++ * ++ * Copyright (C) 2021 ARM Ltd. ++ */ ++ ++#ifndef __CORESIGHT_SELF_HOSTED_TRACE_H ++#define __CORESIGHT_SELF_HOSTED_TRACE_H ++ ++#include ++ ++static inline u64 read_trfcr(void) ++{ ++ return read_sysreg_s(SYS_TRFCR_EL1); ++} ++ ++static inline void write_trfcr(u64 val) ++{ ++ write_sysreg_s(val, SYS_TRFCR_EL1); ++ isb(); ++} ++ ++#endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */ +-- +2.51.0 + diff --git a/queue-5.15/coresight-etm4x-use-trace-filtering-controls-dynamic.patch b/queue-5.15/coresight-etm4x-use-trace-filtering-controls-dynamic.patch new file mode 100644 index 0000000000..4a9a2c3f81 --- /dev/null +++ b/queue-5.15/coresight-etm4x-use-trace-filtering-controls-dynamic.patch @@ -0,0 +1,229 @@ +From b399c200c9d87ac6bc19de0bddb82fcb536f16a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Sep 2021 11:26:33 +0100 +Subject: coresight: etm4x: Use Trace Filtering controls dynamically + +From: Suzuki K Poulose + +[ Upstream commit 5f6fd1aa8cc147b111af1a833574487a87237dc0 ] + +The Trace Filtering support (FEAT_TRF) ensures that the ETM +can be prohibited from generating any trace for a given EL. +This is much stricter knob, than the TRCVICTLR exception level +masks, which doesn't prevent the ETM from generating Context +packets for an "excluded" EL. At the moment, we do a onetime +enable trace at user and kernel and leave it untouched for the +kernel life time. This implies that the ETM could potentially +generate trace packets containing the kernel addresses, and +thus leaking the kernel virtual address in the trace. + +This patch makes the switch dynamic, by honoring the filters +set by the user and enforcing them in the TRFCR controls. +We also rename the cpu_enable_tracing() appropriately to +cpu_detect_trace_filtering() and the drvdata member +trfc => trfcr to indicate the "value" of the TRFCR_EL1. + +Cc: Mathieu Poirier +Cc: Al Grant +Cc: Mike Leach +Cc: Leo Yan +Signed-off-by: Suzuki K Poulose +Reviewed-by: Anshuman Khandual +Link: https://lore.kernel.org/r/20210914102641.1852544-3-suzuki.poulose@arm.com +Signed-off-by: Mathieu Poirier +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 63 ++++++++++++++----- + drivers/hwtracing/coresight/coresight-etm4x.h | 7 ++- + .../coresight/coresight-self-hosted-trace.h | 7 +++ + 3 files changed, 59 insertions(+), 18 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index d124931ee2be5..54e5be46973a3 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -239,6 +239,45 @@ struct etm4_enable_arg { + int rc; + }; + ++/* ++ * etm4x_prohibit_trace - Prohibit the CPU from tracing at all ELs. ++ * When the CPU supports FEAT_TRF, we could move the ETM to a trace ++ * prohibited state by filtering the Exception levels via TRFCR_EL1. ++ */ ++static void etm4x_prohibit_trace(struct etmv4_drvdata *drvdata) ++{ ++ /* If the CPU doesn't support FEAT_TRF, nothing to do */ ++ if (!drvdata->trfcr) ++ return; ++ cpu_prohibit_trace(); ++} ++ ++/* ++ * etm4x_allow_trace - Allow CPU tracing in the respective ELs, ++ * as configured by the drvdata->config.mode for the current ++ * session. Even though we have TRCVICTLR bits to filter the ++ * trace in the ELs, it doesn't prevent the ETM from generating ++ * a packet (e.g, TraceInfo) that might contain the addresses from ++ * the excluded levels. Thus we use the additional controls provided ++ * via the Trace Filtering controls (FEAT_TRF) to make sure no trace ++ * is generated for the excluded ELs. ++ */ ++static void etm4x_allow_trace(struct etmv4_drvdata *drvdata) ++{ ++ u64 trfcr = drvdata->trfcr; ++ ++ /* If the CPU doesn't support FEAT_TRF, nothing to do */ ++ if (!trfcr) ++ return; ++ ++ if (drvdata->config.mode & ETM_MODE_EXCL_KERN) ++ trfcr &= ~TRFCR_ELx_ExTRE; ++ if (drvdata->config.mode & ETM_MODE_EXCL_USER) ++ trfcr &= ~TRFCR_ELx_E0TRE; ++ ++ write_trfcr(trfcr); ++} ++ + #ifdef CONFIG_ETM4X_IMPDEF_FEATURE + + #define HISI_HIP08_AMBA_ID 0x000b6d01 +@@ -445,6 +484,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + if (etm4x_is_ete(drvdata)) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + ++ etm4x_allow_trace(drvdata); + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +@@ -740,7 +780,6 @@ static int etm4_enable(struct coresight_device *csdev, + static void etm4_disable_hw(void *info) + { + u32 control; +- u64 trfcr; + struct etmv4_drvdata *drvdata = info; + struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; +@@ -767,12 +806,7 @@ static void etm4_disable_hw(void *info) + * If the CPU supports v8.4 Trace filter Control, + * set the ETM to trace prohibited region. + */ +- if (drvdata->trfc) { +- trfcr = read_sysreg_s(SYS_TRFCR_EL1); +- write_sysreg_s(trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE), +- SYS_TRFCR_EL1); +- isb(); +- } ++ etm4x_prohibit_trace(drvdata); + /* + * Make sure everything completes before disabling, as recommended + * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +@@ -788,9 +822,6 @@ static void etm4_disable_hw(void *info) + if (coresight_timeout(csa, TRCSTATR, TRCSTATR_PMSTABLE_BIT, 1)) + dev_err(etm_dev, + "timeout while waiting for PM stable Trace Status\n"); +- if (drvdata->trfc) +- write_sysreg_s(trfcr, SYS_TRFCR_EL1); +- + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { + config->ss_status[i] = +@@ -988,15 +1019,15 @@ static bool etm4_init_csdev_access(struct etmv4_drvdata *drvdata, + return false; + } + +-static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) ++static void cpu_detect_trace_filtering(struct etmv4_drvdata *drvdata) + { + u64 dfr0 = read_sysreg(id_aa64dfr0_el1); + u64 trfcr; + ++ drvdata->trfcr = 0; + if (!cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_TRACE_FILT_SHIFT)) + return; + +- drvdata->trfc = true; + /* + * If the CPU supports v8.4 SelfHosted Tracing, enable + * tracing at the kernel EL and EL0, forcing to use the +@@ -1010,7 +1041,7 @@ static void cpu_enable_tracing(struct etmv4_drvdata *drvdata) + if (is_kernel_in_hyp_mode()) + trfcr |= TRFCR_EL2_CX; + +- write_trfcr(trfcr); ++ drvdata->trfcr = trfcr; + } + + static void etm4_init_arch_data(void *info) +@@ -1183,7 +1214,7 @@ static void etm4_init_arch_data(void *info) + /* NUMCNTR, bits[30:28] number of counters available for tracing */ + drvdata->nr_cntr = BMVAL(etmidr5, 28, 30); + etm4_cs_lock(drvdata, csa); +- cpu_enable_tracing(drvdata); ++ cpu_detect_trace_filtering(drvdata); + } + + static inline u32 etm4_get_victlr_access_type(struct etmv4_config *config) +@@ -1680,7 +1711,7 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata) + int ret = 0; + + /* Save the TRFCR irrespective of whether the ETM is ON */ +- if (drvdata->trfc) ++ if (drvdata->trfcr) + drvdata->save_trfcr = read_trfcr(); + /* + * Save and restore the ETM Trace registers only if +@@ -1792,7 +1823,7 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + + static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) + { +- if (drvdata->trfc) ++ if (drvdata->trfcr) + write_trfcr(drvdata->save_trfcr); + if (drvdata->state_needs_restore) + __etm4_cpu_restore(drvdata); +diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h +index 74f1ba8ed148d..85bf733a21bab 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x.h ++++ b/drivers/hwtracing/coresight/coresight-etm4x.h +@@ -899,7 +899,10 @@ struct etmv4_save_state { + * @nooverflow: Indicate if overflow prevention is supported. + * @atbtrig: If the implementation can support ATB triggers + * @lpoverride: If the implementation can support low-power state over. +- * @trfc: If the implementation supports Arm v8.4 trace filter controls. ++ * @trfcr: If the CPU supports FEAT_TRF, value of the TRFCR_ELx that ++ * allows tracing at all ELs. We don't want to compute this ++ * at runtime, due to the additional setting of TRFCR_CX when ++ * in EL2. Otherwise, 0. + * @config: structure holding configuration parameters. + * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. + * @save_state: State to be preserved across power loss +@@ -953,7 +956,7 @@ struct etmv4_drvdata { + bool nooverflow; + bool atbtrig; + bool lpoverride; +- bool trfc; ++ u64 trfcr; + struct etmv4_config config; + u64 save_trfcr; + struct etmv4_save_state *save_state; +diff --git a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h +index 303d71911870f..23f05df3f1730 100644 +--- a/drivers/hwtracing/coresight/coresight-self-hosted-trace.h ++++ b/drivers/hwtracing/coresight/coresight-self-hosted-trace.h +@@ -21,4 +21,11 @@ static inline void write_trfcr(u64 val) + isb(); + } + ++static inline void cpu_prohibit_trace(void) ++{ ++ u64 trfcr = read_trfcr(); ++ ++ /* Prohibit tracing at EL0 & the kernel EL */ ++ write_trfcr(trfcr & ~(TRFCR_ELx_ExTRE | TRFCR_ELx_E0TRE)); ++} + #endif /* __CORESIGHT_SELF_HOSTED_TRACE_H */ +-- +2.51.0 + diff --git a/queue-5.15/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-5.15/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..d0eed96198 --- /dev/null +++ b/queue-5.15/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From eba0ad30d1c27cf2b9e5b29e0152ee4acaa09a40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index ad8af3d70ac04..2e3fa520d6eb1 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -138,12 +139,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-5.15/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-5.15/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..57c371a86f --- /dev/null +++ b/queue-5.15/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From 051a426ecc4bab502a1a8dbb09ab21e94b010363 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index 6140e49273226..5754dc88c684c 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-5.15/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-5.15/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..04a1986b6e --- /dev/null +++ b/queue-5.15/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From 9a9d965657e065c5e22eca2424424b72fd58570a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 58e995db37838..a48c6306a8cb2 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -4010,6 +4010,7 @@ static int qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -4017,6 +4018,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -4030,11 +4032,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-5.15/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-5.15/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..c13a128995 --- /dev/null +++ b/queue-5.15/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 63689a881be9ca34faae5f02312194fcc3492fa2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 6bc8c6bee411e..bebdc9b53bb6b 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1156,10 +1156,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-5.15/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-5.15/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..8986f2f6c9 --- /dev/null +++ b/queue-5.15/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From 64bc7ab740e5900ee31f9eea4a36d77016efe464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 141cb36b9c07b..f1c7d16d30f63 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -85,27 +85,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -124,7 +103,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-5.15/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-5.15/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..871bc2db7d --- /dev/null +++ b/queue-5.15/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From 34cba45cee47e7d1e922622edbb57b4044947b79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 6134432e4918d..2260d5abf1ae8 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -64,7 +64,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + int ret; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-5.15/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-5.15/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..c2da511305 --- /dev/null +++ b/queue-5.15/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From 99d093cf2fbd7f5d571d4a0c3a9505099367937f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index 43fc56d0c4a06..539cf4ee57672 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -94,7 +94,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-5.15/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-5.15/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..261ecf52a8 --- /dev/null +++ b/queue-5.15/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From a49b89d22e236263f150c6118cd556b5d5ab2124 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index a5bd90bc0712e..9c3b8e65c42a3 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-5.15/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch b/queue-5.15/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch new file mode 100644 index 0000000000..5e148fd278 --- /dev/null +++ b/queue-5.15/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch @@ -0,0 +1,244 @@ +From afdd4a2b1c29dc31429c27f75b69b7d3fcfa5603 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Mar 2023 14:27:33 +0100 +Subject: dt-bindings: PCI: convert amlogic,meson-pcie.txt to dt-schema + +From: Neil Armstrong + +[ Upstream commit b80b848bdf56bd402b7a91aea5b77cec93dfe4c2 ] + +Convert the Amlogic Meson AXG DWC PCIe SoC controller bindings to +dt-schema. + +Link: https://lore.kernel.org/r/20221117-b4-amlogic-bindings-convert-v4-5-34e623dbf789@linaro.org +Signed-off-by: Neil Armstrong +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Krzysztof Kozlowski +Stable-dep-of: 4813dea9e272 ("dt-bindings: PCI: amlogic: Fix the register name of the DBI region") +Signed-off-by: Sasha Levin +--- + .../bindings/pci/amlogic,axg-pcie.yaml | 134 ++++++++++++++++++ + .../bindings/pci/amlogic,meson-pcie.txt | 70 --------- + 2 files changed, 134 insertions(+), 70 deletions(-) + create mode 100644 Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml + delete mode 100644 Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +new file mode 100644 +index 0000000000000..a5bd90bc0712e +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -0,0 +1,134 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/pci/amlogic,axg-pcie.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Amlogic Meson AXG DWC PCIe SoC controller ++ ++maintainers: ++ - Neil Armstrong ++ ++description: ++ Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. ++ ++allOf: ++ - $ref: /schemas/pci/pci-bus.yaml# ++ - $ref: /schemas/pci/snps,dw-pcie-common.yaml# ++ ++# We need a select here so we don't match all nodes with 'snps,dw-pcie' ++select: ++ properties: ++ compatible: ++ enum: ++ - amlogic,axg-pcie ++ - amlogic,g12a-pcie ++ required: ++ - compatible ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - amlogic,axg-pcie ++ - amlogic,g12a-pcie ++ - const: snps,dw-pcie ++ ++ reg: ++ items: ++ - description: External local bus interface registers ++ - description: Meson designed configuration registers ++ - description: PCIe configuration space ++ ++ reg-names: ++ items: ++ - const: elbi ++ - const: cfg ++ - const: config ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: PCIe GEN 100M PLL clock ++ - description: PCIe RC clock gate ++ - description: PCIe PHY clock ++ ++ clock-names: ++ items: ++ - const: pclk ++ - const: port ++ - const: general ++ ++ phys: ++ maxItems: 1 ++ ++ phy-names: ++ const: pcie ++ ++ resets: ++ items: ++ - description: Port Reset ++ - description: Shared APB reset ++ ++ reset-names: ++ items: ++ - const: port ++ - const: apb ++ ++ num-lanes: ++ const: 1 ++ ++ power-domains: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ - reg-names ++ - interrupts ++ - clock ++ - clock-names ++ - "#address-cells" ++ - "#size-cells" ++ - "#interrupt-cells" ++ - interrupt-map ++ - interrupt-map-mask ++ - ranges ++ - bus-range ++ - device_type ++ - num-lanes ++ - phys ++ - phy-names ++ - resets ++ - reset-names ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ pcie: pcie@f9800000 { ++ compatible = "amlogic,axg-pcie", "snps,dw-pcie"; ++ reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; ++ reg-names = "elbi", "cfg", "config"; ++ interrupts = ; ++ clocks = <&pclk>, <&clk_port>, <&clk_phy>; ++ clock-names = "pclk", "port", "general"; ++ resets = <&reset_pcie_port>, <&reset_pcie_apb>; ++ reset-names = "port", "apb"; ++ phys = <&pcie_phy>; ++ phy-names = "pcie"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; ++ bus-range = <0x0 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ num-lanes = <1>; ++ ranges = <0x82000000 0 0 0xf9c00000 0 0x00300000>; ++ }; ++... +diff --git a/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt b/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt +deleted file mode 100644 +index c3a75ac6e59d1..0000000000000 +--- a/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt ++++ /dev/null +@@ -1,70 +0,0 @@ +-Amlogic Meson AXG DWC PCIE SoC controller +- +-Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. +-It shares common functions with the PCIe DesignWare core driver and +-inherits common properties defined in +-Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml. +- +-Additional properties are described here: +- +-Required properties: +-- compatible: +- should contain : +- - "amlogic,axg-pcie" for AXG SoC Family +- - "amlogic,g12a-pcie" for G12A SoC Family +- to identify the core. +-- reg: +- should contain the configuration address space. +-- reg-names: Must be +- - "elbi" External local bus interface registers +- - "cfg" Meson specific registers +- - "config" PCIe configuration space +-- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. +-- clocks: Must contain an entry for each entry in clock-names. +-- clock-names: Must include the following entries: +- - "pclk" PCIe GEN 100M PLL clock +- - "port" PCIe_x(A or B) RC clock gate +- - "general" PCIe Phy clock +-- resets: phandle to the reset lines. +-- reset-names: must contain "port" and "apb" +- - "port" Port A or B reset +- - "apb" Share APB reset +-- phys: should contain a phandle to the PCIE phy +-- phy-names: must contain "pcie" +- +-- device_type: +- should be "pci". As specified in snps,dw-pcie.yaml +- +- +-Example configuration: +- +- pcie: pcie@f9800000 { +- compatible = "amlogic,axg-pcie", "snps,dw-pcie"; +- reg = <0x0 0xf9800000 0x0 0x400000 +- 0x0 0xff646000 0x0 0x2000 +- 0x0 0xf9f00000 0x0 0x100000>; +- reg-names = "elbi", "cfg", "config"; +- reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; +- interrupts = ; +- #interrupt-cells = <1>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; +- bus-range = <0x0 0xff>; +- #address-cells = <3>; +- #size-cells = <2>; +- device_type = "pci"; +- ranges = <0x82000000 0 0 0x0 0xf9c00000 0 0x00300000>; +- +- clocks = <&clkc CLKID_USB +- &clkc CLKID_PCIE_A +- &clkc CLKID_PCIE_CML_EN0>; +- clock-names = "general", +- "pclk", +- "port"; +- resets = <&reset RESET_PCIE_A>, +- <&reset RESET_PCIE_APB>; +- reset-names = "port", +- "apb"; +- phys = <&pcie_phy>; +- phy-names = "pcie"; +- }; +-- +2.51.0 + diff --git a/queue-5.15/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-5.15/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..288b590cd7 --- /dev/null +++ b/queue-5.15/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From c6220b3ae76062a0992057c17d24025f2a4fb0a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 4cb1872c9af43..b1ad339165e41 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -473,7 +473,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-5.15/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-5.15/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..e8d3bc544d --- /dev/null +++ b/queue-5.15/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From d380429cb72ff553522392d499eb3bcb66c51b4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 93ff3220511e7..702a3229c39b0 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -663,6 +663,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -707,15 +725,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -731,15 +740,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-5.15/ext4-minor-defrag-code-improvements.patch b/queue-5.15/ext4-minor-defrag-code-improvements.patch new file mode 100644 index 0000000000..1634d063ca --- /dev/null +++ b/queue-5.15/ext4-minor-defrag-code-improvements.patch @@ -0,0 +1,79 @@ +From 65cba4cacaa2bd66d51751a616fc9eb8c6a92ed7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Jul 2022 12:39:10 -0400 +Subject: ext4: minor defrag code improvements + +From: Eric Whitney + +[ Upstream commit d412df530f77d0f61c41b83f925997452fc3944c ] + +Modify the error returns for two file types that can't be defragged to +more clearly communicate those restrictions to a caller. When the +defrag code is applied to swap files, return -ETXTBSY, and when applied +to quota files, return -EOPNOTSUPP. Move an extent tree search whose +results are only occasionally required to the site always requiring them +for improved efficiency. Address a few typos. + +Signed-off-by: Eric Whitney +Link: https://lore.kernel.org/r/20220722163910.268564-1-enwlinux@gmail.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: a2e5a3cea4b1 ("ext4: correct the checking of quota files before moving extents") +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 661a8544d7817..4cb1872c9af43 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -466,19 +466,17 @@ mext_check_arguments(struct inode *orig_inode, + if (IS_IMMUTABLE(donor_inode) || IS_APPEND(donor_inode)) + return -EPERM; + +- /* Ext4 move extent does not support swapfile */ ++ /* Ext4 move extent does not support swap files */ + if (IS_SWAPFILE(orig_inode) || IS_SWAPFILE(donor_inode)) { +- ext4_debug("ext4 move extent: The argument files should " +- "not be swapfile [ino:orig %lu, donor %lu]\n", ++ ext4_debug("ext4 move extent: The argument files should not be swap files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); +- return -EBUSY; ++ return -ETXTBSY; + } + + if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { +- ext4_debug("ext4 move extent: The argument files should " +- "not be quota files [ino:orig %lu, donor %lu]\n", ++ ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); +- return -EBUSY; ++ return -EOPNOTSUPP; + } + + /* Ext4 move extent supports only extent based file */ +@@ -626,11 +624,11 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, + if (ret) + goto out; + ex = path[path->p_depth].p_ext; +- next_blk = ext4_ext_next_allocated_block(path); + cur_blk = le32_to_cpu(ex->ee_block); + cur_len = ext4_ext_get_actual_len(ex); + /* Check hole before the start pos */ + if (cur_blk + cur_len - 1 < o_start) { ++ next_blk = ext4_ext_next_allocated_block(path); + if (next_blk == EXT_MAX_BLOCKS) { + o_start = o_end; + ret = -ENODATA; +@@ -659,7 +657,7 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk, + donor_page_index = d_start >> (PAGE_SHIFT - + donor_inode->i_blkbits); + offset_in_page = o_start % blocks_per_page; +- if (cur_len > blocks_per_page- offset_in_page) ++ if (cur_len > blocks_per_page - offset_in_page) + cur_len = blocks_per_page - offset_in_page; + /* + * Up semaphore to avoid following problems: +-- +2.51.0 + diff --git a/queue-5.15/ext4-remove-unused-return-value-of-__mb_check_buddy.patch b/queue-5.15/ext4-remove-unused-return-value-of-__mb_check_buddy.patch new file mode 100644 index 0000000000..d9b6040445 --- /dev/null +++ b/queue-5.15/ext4-remove-unused-return-value-of-__mb_check_buddy.patch @@ -0,0 +1,63 @@ +From 92ab8edc7824cab4a4e4fabe9d6d03aac43fbc0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Jan 2024 17:20:54 +0800 +Subject: ext4: remove unused return value of __mb_check_buddy + +From: Kemeng Shi + +[ Upstream commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 ] + +Remove unused return value of __mb_check_buddy. + +Signed-off-by: Kemeng Shi +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240105092102.496631-2-shikemeng@huaweicloud.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation") +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 1a8d72c5e327a..93ff3220511e7 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -663,7 +663,7 @@ do { \ + } \ + } while (0) + +-static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, ++static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { + struct super_block *sb = e4b->bd_sb; +@@ -682,7 +682,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + void *buddy2; + + if (e4b->bd_info->bb_check_counter++ % 10) +- return 0; ++ return; + + while (order > 1) { + buddy = mb_find_buddy(e4b, order, &max); +@@ -747,7 +747,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + + grp = ext4_get_group_info(sb, e4b->bd_group); + if (!grp) +- return NULL; ++ return; + list_for_each(cur, &grp->bb_prealloc_list) { + ext4_group_t groupnr; + struct ext4_prealloc_space *pa; +@@ -757,7 +757,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + for (i = 0; i < pa->pa_len; i++) + MB_CHECK_ASSERT(mb_test_bit(k + i, buddy)); + } +- return 0; + } + #undef MB_CHECK_ASSERT + #define mb_check_buddy(e4b) __mb_check_buddy(e4b, \ +-- +2.51.0 + diff --git a/queue-5.15/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-5.15/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..d33b93e01e --- /dev/null +++ b/queue-5.15/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From 5f60f3cc8662cfcf041adfdcfe7d41d1560029ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index 7acf7c0b263e6..212494b0a4ba8 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -732,7 +732,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -812,6 +812,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-5.15/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-5.15/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..069cd07808 --- /dev/null +++ b/queue-5.15/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From 9719ff6fc47563ec991f0720f655e038b119d2f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index d9dcc20945c6a..32b1ca4e10508 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -160,8 +160,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-add-new-argument-is_mft-to-ntfs_mark_rec_fr.patch b/queue-5.15/fs-ntfs3-add-new-argument-is_mft-to-ntfs_mark_rec_fr.patch new file mode 100644 index 0000000000..0e26303fa0 --- /dev/null +++ b/queue-5.15/fs-ntfs3-add-new-argument-is_mft-to-ntfs_mark_rec_fr.patch @@ -0,0 +1,139 @@ +From 8807c0f804b2dd65c978dbe0eb0bad30647ae18c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jun 2022 19:14:43 +0300 +Subject: fs/ntfs3: Add new argument is_mft to ntfs_mark_rec_free + +From: Konstantin Komarov + +[ Upstream commit 071100ea0e6c353258f322cb2f8dde9be62d6808 ] + +This argument helps in avoiding double locking + +Signed-off-by: Konstantin Komarov +Stable-dep-of: 4d78d1173a65 ("fs/ntfs3: out1 also needs to put mi") +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 12 ++++++------ + fs/ntfs3/fsntfs.c | 9 ++++++--- + fs/ntfs3/inode.c | 2 +- + fs/ntfs3/ntfs_fs.h | 2 +- + 4 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index a74bbfec8e3ac..b5f3e7bc5d6da 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1037,7 +1037,7 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + err = -EINVAL; + + out1: +- ntfs_mark_rec_free(sbi, rno); ++ ntfs_mark_rec_free(sbi, rno, is_mft); + + out: + return err; +@@ -1232,7 +1232,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni) + mft_min = mft_new; + mi_min = mi_new; + } else { +- ntfs_mark_rec_free(sbi, mft_new); ++ ntfs_mark_rec_free(sbi, mft_new, true); + mft_new = 0; + ni_remove_mi(ni, mi_new); + } +@@ -1315,7 +1315,7 @@ static int ni_expand_mft_list(struct ntfs_inode *ni) + + out: + if (mft_new) { +- ntfs_mark_rec_free(sbi, mft_new); ++ ntfs_mark_rec_free(sbi, mft_new, true); + ni_remove_mi(ni, mi_new); + } + +@@ -1577,7 +1577,7 @@ int ni_delete_all(struct ntfs_inode *ni) + mi->dirty = true; + mi_write(mi, 0); + +- ntfs_mark_rec_free(sbi, mi->rno); ++ ntfs_mark_rec_free(sbi, mi->rno, false); + ni_remove_mi(ni, mi); + mi_put(mi); + node = next; +@@ -1588,7 +1588,7 @@ int ni_delete_all(struct ntfs_inode *ni) + ni->mi.dirty = true; + err = mi_write(&ni->mi, 0); + +- ntfs_mark_rec_free(sbi, ni->mi.rno); ++ ntfs_mark_rec_free(sbi, ni->mi.rno, false); + + return err; + } +@@ -3292,7 +3292,7 @@ int ni_write_inode(struct inode *inode, int sync, const char *hint) + err = err2; + + if (is_empty) { +- ntfs_mark_rec_free(sbi, mi->rno); ++ ntfs_mark_rec_free(sbi, mi->rno, false); + rb_erase(node, &ni->mi_tree); + mi_put(mi); + } +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index c82398194cd10..7dc2ae7dec591 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -703,12 +703,14 @@ int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft, + + /* + * ntfs_mark_rec_free - Mark record as free. ++ * is_mft - true if we are changing MFT + */ +-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno) ++void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft) + { + struct wnd_bitmap *wnd = &sbi->mft.bitmap; + +- down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT); ++ if (!is_mft) ++ down_write_nested(&wnd->rw_lock, BITMAP_MUTEX_MFT); + if (rno >= wnd->nbits) + goto out; + +@@ -727,7 +729,8 @@ void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno) + sbi->mft.next_free = rno; + + out: +- up_write(&wnd->rw_lock); ++ if (!is_mft) ++ up_write(&wnd->rw_lock); + } + + /* +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 0f4e166112de1..7ac76e6c35dcf 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1668,7 +1668,7 @@ struct inode *ntfs_create_inode(struct user_namespace *mnt_userns, + ni->mi.dirty = false; + discard_new_inode(inode); + out3: +- ntfs_mark_rec_free(sbi, ino); ++ ntfs_mark_rec_free(sbi, ino, false); + + out2: + __putname(new_de); +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index f7ef60bed6d84..69d1442eea623 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -596,7 +596,7 @@ int ntfs_look_for_free_space(struct ntfs_sb_info *sbi, CLST lcn, CLST len, + enum ALLOCATE_OPT opt); + int ntfs_look_free_mft(struct ntfs_sb_info *sbi, CLST *rno, bool mft, + struct ntfs_inode *ni, struct mft_inode **mi); +-void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno); ++void ntfs_mark_rec_free(struct ntfs_sb_info *sbi, CLST rno, bool is_mft); + int ntfs_clear_mft_tail(struct ntfs_sb_info *sbi, size_t from, size_t to); + int ntfs_refresh_zone(struct ntfs_sb_info *sbi); + int ntfs_update_mftmirr(struct ntfs_sb_info *sbi, int wait); +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-make-ni_ins_new_attr-return-error.patch b/queue-5.15/fs-ntfs3-make-ni_ins_new_attr-return-error.patch new file mode 100644 index 0000000000..8c05a12a3e --- /dev/null +++ b/queue-5.15/fs-ntfs3-make-ni_ins_new_attr-return-error.patch @@ -0,0 +1,105 @@ +From 924e31677f9af28855d37df0eb2a082c4347123f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 13 Jul 2022 19:18:19 +0300 +Subject: fs/ntfs3: Make ni_ins_new_attr return error + +From: Konstantin Komarov + +[ Upstream commit 451e45a0e6df21e63acfd493feb5194f4697ce11 ] + +Function ni_ins_new_attr now returns ERR_PTR(err), +so we check it now in other functions like ni_expand_mft_list + +Signed-off-by: Konstantin Komarov +Stable-dep-of: 4d78d1173a65 ("fs/ntfs3: out1 also needs to put mi") +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 29 ++++++++++++++++++++++++++--- + 1 file changed, 26 insertions(+), 3 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index b5f3e7bc5d6da..4db52dfde6328 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -470,7 +470,7 @@ ni_ins_new_attr(struct ntfs_inode *ni, struct mft_inode *mi, + &ref, &le); + if (err) { + /* No memory or no space. */ +- return NULL; ++ return ERR_PTR(err); + } + le_added = true; + +@@ -1000,6 +1000,8 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + name_off, svcn, ins_le); + if (!attr) + continue; ++ if (IS_ERR(attr)) ++ return PTR_ERR(attr); + + if (ins_attr) + *ins_attr = attr; +@@ -1021,8 +1023,15 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + attr = ni_ins_new_attr(ni, mi, le, type, name, name_len, asize, + name_off, svcn, ins_le); +- if (!attr) ++ if (!attr) { ++ err = -EINVAL; + goto out2; ++ } ++ ++ if (IS_ERR(attr)) { ++ err = PTR_ERR(attr); ++ goto out2; ++ } + + if (ins_attr) + *ins_attr = attr; +@@ -1034,7 +1043,6 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + out2: + ni_remove_mi(ni, mi); + mi_put(mi); +- err = -EINVAL; + + out1: + ntfs_mark_rec_free(sbi, rno, is_mft); +@@ -1090,6 +1098,11 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, + if (asize <= free) { + attr = ni_ins_new_attr(ni, &ni->mi, NULL, type, name, name_len, + asize, name_off, svcn, ins_le); ++ if (IS_ERR(attr)) { ++ err = PTR_ERR(attr); ++ goto out; ++ } ++ + if (attr) { + if (ins_attr) + *ins_attr = attr; +@@ -1187,6 +1200,11 @@ static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type, + goto out; + } + ++ if (IS_ERR(attr)) { ++ err = PTR_ERR(attr); ++ goto out; ++ } ++ + if (ins_attr) + *ins_attr = attr; + if (ins_mi) +@@ -1302,6 +1320,11 @@ static int ni_expand_mft_list(struct ntfs_inode *ni) + goto out; + } + ++ if (IS_ERR(attr)) { ++ err = PTR_ERR(attr); ++ goto out; ++ } ++ + attr->non_res = 1; + attr->name_off = SIZEOF_NONRESIDENT_LE; + attr->flags = 0; +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-5.15/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..695a15ffd5 --- /dev/null +++ b/queue-5.15/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From 36f511acc29f8f053d68c02cf24997ed58c6e11b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 4db52dfde6328..89ee218706678 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1042,9 +1042,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-5.15/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..88cad8a807 --- /dev/null +++ b/queue-5.15/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From f926498d923049e8fc720888924880e6b699d65e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 89ee218706678..62874e7f8d8f1 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -376,8 +376,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-5.15/fs-ntfs3-remove-unused-mi_mark_free.patch b/queue-5.15/fs-ntfs3-remove-unused-mi_mark_free.patch new file mode 100644 index 0000000000..94b52cf3f0 --- /dev/null +++ b/queue-5.15/fs-ntfs3-remove-unused-mi_mark_free.patch @@ -0,0 +1,96 @@ +From d2529d783832c9251d2414c8fcb33a6e771e25b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Jun 2022 18:49:24 +0300 +Subject: fs/ntfs3: Remove unused mi_mark_free + +From: Konstantin Komarov + +[ Upstream commit 6700eabb90d50c50be21ecbb71131cd6ecf91ded ] + +Cleaning up dead code +Fix wrong comments + +Signed-off-by: Konstantin Komarov +Stable-dep-of: 4d78d1173a65 ("fs/ntfs3: out1 also needs to put mi") +Signed-off-by: Sasha Levin +--- + fs/ntfs3/namei.c | 2 +- + fs/ntfs3/ntfs_fs.h | 1 - + fs/ntfs3/record.c | 22 ---------------------- + fs/ntfs3/super.c | 2 +- + 4 files changed, 2 insertions(+), 25 deletions(-) + +diff --git a/fs/ntfs3/namei.c b/fs/ntfs3/namei.c +index c1bce9d656cff..b66694b84caa0 100644 +--- a/fs/ntfs3/namei.c ++++ b/fs/ntfs3/namei.c +@@ -218,7 +218,7 @@ static int ntfs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, + } + + /* +- * ntfs_rmdir - inode_operations::rm_dir ++ * ntfs_rmdir - inode_operations::rmdir + */ + static int ntfs_rmdir(struct inode *dir, struct dentry *dentry) + { +diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h +index 7b46926e920c6..f7ef60bed6d84 100644 +--- a/fs/ntfs3/ntfs_fs.h ++++ b/fs/ntfs3/ntfs_fs.h +@@ -740,7 +740,6 @@ static inline struct ATTRIB *rec_find_attr_le(struct mft_inode *rec, + int mi_write(struct mft_inode *mi, int wait); + int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno, + __le16 flags, bool is_mft); +-void mi_mark_free(struct mft_inode *mi); + struct ATTRIB *mi_insert_attr(struct mft_inode *mi, enum ATTR_TYPE type, + const __le16 *name, u8 name_len, u32 asize, + u16 name_off); +diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c +index 383fc3437f02e..cef53583f9a16 100644 +--- a/fs/ntfs3/record.c ++++ b/fs/ntfs3/record.c +@@ -405,28 +405,6 @@ int mi_format_new(struct mft_inode *mi, struct ntfs_sb_info *sbi, CLST rno, + return err; + } + +-/* +- * mi_mark_free - Mark record as unused and marks it as free in bitmap. +- */ +-void mi_mark_free(struct mft_inode *mi) +-{ +- CLST rno = mi->rno; +- struct ntfs_sb_info *sbi = mi->sbi; +- +- if (rno >= MFT_REC_RESERVED && rno < MFT_REC_FREE) { +- ntfs_clear_mft_tail(sbi, rno, rno + 1); +- mi->dirty = false; +- return; +- } +- +- if (mi->mrec) { +- clear_rec_inuse(mi->mrec); +- mi->dirty = true; +- mi_write(mi, 0); +- } +- ntfs_mark_rec_free(sbi, rno); +-} +- + /* + * mi_insert_attr - Reserve space for new attribute. + * +diff --git a/fs/ntfs3/super.c b/fs/ntfs3/super.c +index 78b0865273317..a9952b0321837 100644 +--- a/fs/ntfs3/super.c ++++ b/fs/ntfs3/super.c +@@ -1382,7 +1382,7 @@ static const struct fs_context_operations ntfs_context_ops = { + /* + * ntfs_init_fs_context - Initialize spi and opts + * +- * This will called when mount/remount. We will first initiliaze ++ * This will called when mount/remount. We will first initialize + * options so that if remount we can use just that. + */ + static int ntfs_init_fs_context(struct fs_context *fc) +-- +2.51.0 + diff --git a/queue-5.15/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-5.15/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..f24d551525 --- /dev/null +++ b/queue-5.15/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 499d512890d4bb2be126eaf4156658b3adaeefbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index a89a408182e60..c36197eab6fe4 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -394,8 +394,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -418,7 +416,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-5.15/i3c-allow-of-alias-based-persistent-bus-numbering.patch b/queue-5.15/i3c-allow-of-alias-based-persistent-bus-numbering.patch new file mode 100644 index 0000000000..b80a854f0e --- /dev/null +++ b/queue-5.15/i3c-allow-of-alias-based-persistent-bus-numbering.patch @@ -0,0 +1,121 @@ +From c021a3d48ea2b4c728c8c90773efd52a8b637dff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Apr 2023 17:41:49 +0800 +Subject: i3c: Allow OF-alias-based persistent bus numbering + +From: Jeremy Kerr + +[ Upstream commit 7dc2e0a875645a79f5c1c063019397e8e94008f5 ] + +Parse the /aliases node to assign any fixed bus numbers, as is done with +the i2c subsystem. Numbering for non-aliased busses will start after the +highest fixed bus number. + +This allows an alias node such as: + + aliases { + i3c0 = &bus_a, + i3c4 = &bus_b, + }; + +to set the numbering for a set of i3c controllers: + + /* fixed-numbered bus, assigned "i3c-0" */ + bus_a: i3c-master { + }; + + /* another fixed-numbered bus, assigned "i3c-4" */ + bus_b: i3c-master { + }; + + /* dynamic-numbered bus, likely assigned "i3c-5" */ + bus_c: i3c-master { + }; + +If no i3c device aliases are present, the numbering will stay as-is, +starting from 0. + +Signed-off-by: Jeremy Kerr +Link: https://lore.kernel.org/r/20230405094149.1513209-1-jk@codeconstruct.com.au +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index ae60eb7b27601..209aa1e889044 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -21,6 +21,7 @@ + + static DEFINE_IDR(i3c_bus_idr); + static DEFINE_MUTEX(i3c_core_lock); ++static int __i3c_first_dynamic_bus_num; + + /** + * i3c_bus_maintenance_lock - Lock the bus for a maintenance operation +@@ -420,9 +421,9 @@ static void i3c_bus_cleanup(struct i3c_bus *i3cbus) + mutex_unlock(&i3c_core_lock); + } + +-static int i3c_bus_init(struct i3c_bus *i3cbus) ++static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np) + { +- int ret; ++ int ret, start, end, id = -1; + + init_rwsem(&i3cbus->lock); + INIT_LIST_HEAD(&i3cbus->devs.i2c); +@@ -430,8 +431,19 @@ static int i3c_bus_init(struct i3c_bus *i3cbus) + i3c_bus_init_addrslots(i3cbus); + i3cbus->mode = I3C_BUS_MODE_PURE; + ++ if (np) ++ id = of_alias_get_id(np, "i3c"); ++ + mutex_lock(&i3c_core_lock); +- ret = idr_alloc(&i3c_bus_idr, i3cbus, 0, 0, GFP_KERNEL); ++ if (id >= 0) { ++ start = id; ++ end = start + 1; ++ } else { ++ start = __i3c_first_dynamic_bus_num; ++ end = 0; ++ } ++ ++ ret = idr_alloc(&i3c_bus_idr, i3cbus, start, end, GFP_KERNEL); + mutex_unlock(&i3c_core_lock); + + if (ret < 0) +@@ -2607,7 +2619,7 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus); ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); + if (ret) + return ret; + +@@ -2816,8 +2828,16 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) + + static int __init i3c_init(void) + { +- int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); ++ int res; ++ ++ res = of_alias_get_highest_id("i3c"); ++ if (res >= 0) { ++ mutex_lock(&i3c_core_lock); ++ __i3c_first_dynamic_bus_num = res + 1; ++ mutex_unlock(&i3c_core_lock); ++ } + ++ res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); + if (res) + return res; + +-- +2.51.0 + diff --git a/queue-5.15/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-5.15/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..42e37b6a4b --- /dev/null +++ b/queue-5.15/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From 6c6a4ec9c5476bdb1dac23befaecdeac75b064cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 459399cd70da7..e5a282053e2a9 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2619,10 +2619,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2630,6 +2626,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-5.15/i3c-master-inherit-dma-masks-and-parameters-from-par.patch b/queue-5.15/i3c-master-inherit-dma-masks-and-parameters-from-par.patch new file mode 100644 index 0000000000..5750003776 --- /dev/null +++ b/queue-5.15/i3c-master-inherit-dma-masks-and-parameters-from-par.patch @@ -0,0 +1,40 @@ +From 06f0b8c88899401cb78d695eb74baf4deb552847 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:53 +0300 +Subject: i3c: master: Inherit DMA masks and parameters from parent device + +From: Jarkko Nikula + +[ Upstream commit 0c35691551387e060e6ae7a6652b4101270c73cf ] + +Copy the DMA masks and parameters for an I3C master device from parent +device so that the master device has them set for the DMA buffer and +mapping API. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-2-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 209aa1e889044..459399cd70da7 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2626,6 +2626,10 @@ int i3c_master_register(struct i3c_master_controller *master, + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + ++ master->dev.dma_mask = parent->dma_mask; ++ master->dev.coherent_dma_mask = parent->coherent_dma_mask; ++ master->dev.dma_parms = parent->dma_parms; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-5.15/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-5.15/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..5c4e6e9576 --- /dev/null +++ b/queue-5.15/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From df837cca1a0dd22ca91b01f5ab2f687b4d1abc32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index 27f55b5e388d9..d12b4ff2a4495 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -297,21 +297,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-5.15/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch b/queue-5.15/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch new file mode 100644 index 0000000000..c9b2f52148 --- /dev/null +++ b/queue-5.15/i3c-remove-i2c-board-info-from-i2c_dev_desc.patch @@ -0,0 +1,104 @@ +From 85c791dc850da64b6c09c181c5564d358fbdaaec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jan 2022 17:48:15 +0000 +Subject: i3c: remove i2c board info from i2c_dev_desc + +From: Jamie Iles + +[ Upstream commit 31b9887c7258ca47d9c665a80f19f006c86756b1 ] + +I2C board info is only required during adapter setup so there is no +requirement to keeping a pointer to it once running. To support dynamic +device addition we can't rely on board info - user-space creation +through sysfs won't have a boardinfo. + +Cc: Alexandre Belloni +Signed-off-by: Jamie Iles +Signed-off-by: Alexandre Belloni +Link: https://lore.kernel.org/r/20220117174816.1963463-2-quic_jiles@quicinc.com +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 18 ++++++++++-------- + include/linux/i3c/master.h | 1 - + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 717b337f9e22d..d4e9299472679 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -610,7 +610,7 @@ static void i3c_master_free_i2c_dev(struct i2c_dev_desc *dev) + + static struct i2c_dev_desc * + i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, +- const struct i2c_dev_boardinfo *boardinfo) ++ u16 addr, u8 lvr) + { + struct i2c_dev_desc *dev; + +@@ -619,9 +619,8 @@ i3c_master_alloc_i2c_dev(struct i3c_master_controller *master, + return ERR_PTR(-ENOMEM); + + dev->common.master = master; +- dev->boardinfo = boardinfo; +- dev->addr = boardinfo->base.addr; +- dev->lvr = boardinfo->lvr; ++ dev->addr = addr; ++ dev->lvr = lvr; + + return dev; + } +@@ -695,7 +694,7 @@ i3c_master_find_i2c_dev_by_addr(const struct i3c_master_controller *master, + struct i2c_dev_desc *dev; + + i3c_bus_for_each_i2cdev(&master->bus, dev) { +- if (dev->boardinfo->base.addr == addr) ++ if (dev->addr == addr) + return dev; + } + +@@ -1692,7 +1691,9 @@ static int i3c_master_bus_init(struct i3c_master_controller *master) + i2cboardinfo->base.addr, + I3C_ADDR_SLOT_I2C_DEV); + +- i2cdev = i3c_master_alloc_i2c_dev(master, i2cboardinfo); ++ i2cdev = i3c_master_alloc_i2c_dev(master, ++ i2cboardinfo->base.addr, ++ i2cboardinfo->lvr); + if (IS_ERR(i2cdev)) { + ret = PTR_ERR(i2cdev); + goto err_detach_devs; +@@ -2178,6 +2179,7 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + { + struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master); + struct i2c_dev_desc *i2cdev; ++ struct i2c_dev_boardinfo *i2cboardinfo; + int ret; + + adap->dev.parent = master->dev.parent; +@@ -2197,8 +2199,8 @@ static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + * We silently ignore failures here. The bus should keep working + * correctly even if one or more i2c devices are not registered. + */ +- i3c_bus_for_each_i2cdev(&master->bus, i2cdev) +- i2cdev->dev = i2c_new_client_device(adap, &i2cdev->boardinfo->base); ++ list_for_each_entry(i2cboardinfo, &master->boardinfo.i2c, node) ++ i2cdev->dev = i2c_new_client_device(adap, &i2cboardinfo->base); + + return 0; + } +diff --git a/include/linux/i3c/master.h b/include/linux/i3c/master.h +index 9cb39d901cd5f..604a126b78c83 100644 +--- a/include/linux/i3c/master.h ++++ b/include/linux/i3c/master.h +@@ -85,7 +85,6 @@ struct i2c_dev_boardinfo { + */ + struct i2c_dev_desc { + struct i3c_i2c_dev_desc common; +- const struct i2c_dev_boardinfo *boardinfo; + struct i2c_client *dev; + u16 addr; + u8 lvr; +-- +2.51.0 + diff --git a/queue-5.15/i3c-support-dynamically-added-i2c-devices.patch b/queue-5.15/i3c-support-dynamically-added-i2c-devices.patch new file mode 100644 index 0000000000..d44d46a62f --- /dev/null +++ b/queue-5.15/i3c-support-dynamically-added-i2c-devices.patch @@ -0,0 +1,187 @@ +From ebd98f6d964e045e332a0380adf21fc121f2ea7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Jan 2022 17:48:16 +0000 +Subject: i3c: support dynamically added i2c devices + +From: Jamie Iles + +[ Upstream commit 72a4501b5d089772671360a6ec74d5350acf8c2e ] + +I2C devices can be added to the system dynamically through several +sources other than static board info including device tree overlays and +sysfs i2c new_device. + +Add an I2C bus notifier to attach the clients at runtime if they were +not defined in the board info. For DT devices find the LVR in the reg +property, for user-space new_device additions we synthesize a +conservative setting of no spike filters and fast mode only. + +Cc: Alexandre Belloni +Signed-off-by: Jamie Iles +Signed-off-by: Alexandre Belloni +Link: https://lore.kernel.org/r/20220117174816.1963463-3-quic_jiles@quicinc.com +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 128 ++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 127 insertions(+), 1 deletion(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index d4e9299472679..ae60eb7b27601 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2170,11 +2170,122 @@ static u32 i3c_master_i2c_funcs(struct i2c_adapter *adapter) + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; + } + ++static u8 i3c_master_i2c_get_lvr(struct i2c_client *client) ++{ ++ /* Fall back to no spike filters and FM bus mode. */ ++ u8 lvr = I3C_LVR_I2C_INDEX(2) | I3C_LVR_I2C_FM_MODE; ++ ++ if (client->dev.of_node) { ++ u32 reg[3]; ++ ++ if (!of_property_read_u32_array(client->dev.of_node, "reg", ++ reg, ARRAY_SIZE(reg))) ++ lvr = reg[2]; ++ } ++ ++ return lvr; ++} ++ ++static int i3c_master_i2c_attach(struct i2c_adapter *adap, struct i2c_client *client) ++{ ++ struct i3c_master_controller *master = i2c_adapter_to_i3c_master(adap); ++ enum i3c_addr_slot_status status; ++ struct i2c_dev_desc *i2cdev; ++ int ret; ++ ++ /* Already added by board info? */ ++ if (i3c_master_find_i2c_dev_by_addr(master, client->addr)) ++ return 0; ++ ++ status = i3c_bus_get_addr_slot_status(&master->bus, client->addr); ++ if (status != I3C_ADDR_SLOT_FREE) ++ return -EBUSY; ++ ++ i3c_bus_set_addr_slot_status(&master->bus, client->addr, ++ I3C_ADDR_SLOT_I2C_DEV); ++ ++ i2cdev = i3c_master_alloc_i2c_dev(master, client->addr, ++ i3c_master_i2c_get_lvr(client)); ++ if (IS_ERR(i2cdev)) { ++ ret = PTR_ERR(i2cdev); ++ goto out_clear_status; ++ } ++ ++ ret = i3c_master_attach_i2c_dev(master, i2cdev); ++ if (ret) ++ goto out_free_dev; ++ ++ return 0; ++ ++out_free_dev: ++ i3c_master_free_i2c_dev(i2cdev); ++out_clear_status: ++ i3c_bus_set_addr_slot_status(&master->bus, client->addr, ++ I3C_ADDR_SLOT_FREE); ++ ++ return ret; ++} ++ ++static int i3c_master_i2c_detach(struct i2c_adapter *adap, struct i2c_client *client) ++{ ++ struct i3c_master_controller *master = i2c_adapter_to_i3c_master(adap); ++ struct i2c_dev_desc *dev; ++ ++ dev = i3c_master_find_i2c_dev_by_addr(master, client->addr); ++ if (!dev) ++ return -ENODEV; ++ ++ i3c_master_detach_i2c_dev(dev); ++ i3c_bus_set_addr_slot_status(&master->bus, dev->addr, ++ I3C_ADDR_SLOT_FREE); ++ i3c_master_free_i2c_dev(dev); ++ ++ return 0; ++} ++ + static const struct i2c_algorithm i3c_master_i2c_algo = { + .master_xfer = i3c_master_i2c_adapter_xfer, + .functionality = i3c_master_i2c_funcs, + }; + ++static int i3c_i2c_notifier_call(struct notifier_block *nb, unsigned long action, ++ void *data) ++{ ++ struct i2c_adapter *adap; ++ struct i2c_client *client; ++ struct device *dev = data; ++ struct i3c_master_controller *master; ++ int ret; ++ ++ if (dev->type != &i2c_client_type) ++ return 0; ++ ++ client = to_i2c_client(dev); ++ adap = client->adapter; ++ ++ if (adap->algo != &i3c_master_i2c_algo) ++ return 0; ++ ++ master = i2c_adapter_to_i3c_master(adap); ++ ++ i3c_bus_maintenance_lock(&master->bus); ++ switch (action) { ++ case BUS_NOTIFY_ADD_DEVICE: ++ ret = i3c_master_i2c_attach(adap, client); ++ break; ++ case BUS_NOTIFY_DEL_DEVICE: ++ ret = i3c_master_i2c_detach(adap, client); ++ break; ++ } ++ i3c_bus_maintenance_unlock(&master->bus); ++ ++ return ret; ++} ++ ++static struct notifier_block i2cdev_notifier = { ++ .notifier_call = i3c_i2c_notifier_call, ++}; ++ + static int i3c_master_i2c_adapter_init(struct i3c_master_controller *master) + { + struct i2c_adapter *adap = i3c_master_to_i2c_adapter(master); +@@ -2705,12 +2816,27 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) + + static int __init i3c_init(void) + { +- return bus_register(&i3c_bus_type); ++ int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); ++ ++ if (res) ++ return res; ++ ++ res = bus_register(&i3c_bus_type); ++ if (res) ++ goto out_unreg_notifier; ++ ++ return 0; ++ ++out_unreg_notifier: ++ bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); ++ ++ return res; + } + subsys_initcall(i3c_init); + + static void __exit i3c_exit(void) + { ++ bus_unregister_notifier(&i2c_bus_type, &i2cdev_notifier); + idr_destroy(&i3c_bus_idr); + bus_unregister(&i3c_bus_type); + } +-- +2.51.0 + diff --git a/queue-5.15/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch b/queue-5.15/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch new file mode 100644 index 0000000000..49c32d2f58 --- /dev/null +++ b/queue-5.15/iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch @@ -0,0 +1,199 @@ +From c5032020a0331c89aea71428a44181dc19457c28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Feb 2023 12:14:56 +0100 +Subject: iio: imu: st_lsm6dsx: discard samples during filters settling time + +From: Lorenzo Bianconi + +[ Upstream commit db3c490503bee4d0611f9fc17fcd8cfe6fcdbcad ] + +During digital filters settling time the driver is expected to drop +samples since they can be corrupted. Introduce the capability to drop +a given number of samples according to the configured ODR. +Add sample_to_discard for LSM6DSM-like sensors since new generation +devices (e.g. LSM6DSO) support DRDY mask where corrupted samples are +masked in hw with values greather than 0x7ffd so the driver can easily +discard them. +I have not added sample_to_discard support for LSM6DS3 or LSM6DS3H since +I do not have any sample for testing at the moment. + +Reported-by: Philippe De Muyter +Tested-by: Philippe De Muyter +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/21dcd94935c147ef9b1da4984b3da6264ee9609e.1677496295.git.lorenzo@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: c6d702f2b771 ("iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member") +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 ++++ + .../iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 57 ++++++++++++++++--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 18 ++++++ + 3 files changed, 78 insertions(+), 8 deletions(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 6a6e963fe9731..d448c802572eb 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -124,6 +124,13 @@ struct st_lsm6dsx_odr_table_entry { + int odr_len; + }; + ++struct st_lsm6dsx_samples_to_discard { ++ struct { ++ u32 milli_hz; ++ u16 samples; ++ } val[ST_LSM6DSX_ODR_LIST_SIZE]; ++}; ++ + struct st_lsm6dsx_fs { + u32 gain; + u8 val; +@@ -286,6 +293,7 @@ struct st_lsm6dsx_ext_dev_settings { + * @irq_config: interrupts related registers. + * @drdy_mask: register info for data-ready mask (addr + mask). + * @odr_table: Hw sensors odr table (Hz + val). ++ * @samples_to_discard: Number of samples to discard for filters settling time. + * @fs_table: Hw sensors gain table (gain + val). + * @decimator: List of decimator register info (addr + mask). + * @batch: List of FIFO batching register info (addr + mask). +@@ -319,6 +327,7 @@ struct st_lsm6dsx_settings { + } irq_config; + struct st_lsm6dsx_reg drdy_mask; + struct st_lsm6dsx_odr_table_entry odr_table[2]; ++ struct st_lsm6dsx_samples_to_discard samples_to_discard[2]; + struct st_lsm6dsx_fs_table_entry fs_table[2]; + struct st_lsm6dsx_reg decimator[ST_LSM6DSX_ID_MAX]; + struct st_lsm6dsx_reg batch[2]; +@@ -340,6 +349,7 @@ enum st_lsm6dsx_fifo_mode { + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. + * @odr: Output data rate of the sensor [Hz]. ++ * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. + * @sip: Number of samples in a given pattern. +@@ -354,6 +364,7 @@ struct st_lsm6dsx_sensor { + u32 gain; + u32 odr; + ++ u16 samples_to_discard; + u16 watermark; + u8 decimator; + u8 sip; +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +index 9ebaf73561336..635a9018e7dba 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +@@ -459,17 +459,31 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) + } + + if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { +- iio_push_to_buffers_with_timestamp( +- hw->iio_devs[ST_LSM6DSX_ID_GYRO], +- &hw->scan[ST_LSM6DSX_ID_GYRO], +- gyro_sensor->ts_ref + ts); ++ /* ++ * We need to discards gyro samples during ++ * filters settling time ++ */ ++ if (gyro_sensor->samples_to_discard > 0) ++ gyro_sensor->samples_to_discard--; ++ else ++ iio_push_to_buffers_with_timestamp( ++ hw->iio_devs[ST_LSM6DSX_ID_GYRO], ++ &hw->scan[ST_LSM6DSX_ID_GYRO], ++ gyro_sensor->ts_ref + ts); + gyro_sip--; + } + if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { +- iio_push_to_buffers_with_timestamp( +- hw->iio_devs[ST_LSM6DSX_ID_ACC], +- &hw->scan[ST_LSM6DSX_ID_ACC], +- acc_sensor->ts_ref + ts); ++ /* ++ * We need to discards accel samples during ++ * filters settling time ++ */ ++ if (acc_sensor->samples_to_discard > 0) ++ acc_sensor->samples_to_discard--; ++ else ++ iio_push_to_buffers_with_timestamp( ++ hw->iio_devs[ST_LSM6DSX_ID_ACC], ++ &hw->scan[ST_LSM6DSX_ID_ACC], ++ acc_sensor->ts_ref + ts); + acc_sip--; + } + if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { +@@ -659,6 +673,30 @@ int st_lsm6dsx_flush_fifo(struct st_lsm6dsx_hw *hw) + return err; + } + ++static void ++st_lsm6dsx_update_samples_to_discard(struct st_lsm6dsx_sensor *sensor) ++{ ++ const struct st_lsm6dsx_samples_to_discard *data; ++ struct st_lsm6dsx_hw *hw = sensor->hw; ++ int i; ++ ++ if (sensor->id != ST_LSM6DSX_ID_GYRO && ++ sensor->id != ST_LSM6DSX_ID_ACC) ++ return; ++ ++ /* check if drdy mask is supported in hw */ ++ if (hw->settings->drdy_mask.addr) ++ return; ++ ++ data = &hw->settings->samples_to_discard[sensor->id]; ++ for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) { ++ if (data->val[i].milli_hz == sensor->odr) { ++ sensor->samples_to_discard = data->val[i].samples; ++ return; ++ } ++ } ++} ++ + int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + { + struct st_lsm6dsx_hw *hw = sensor->hw; +@@ -678,6 +716,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + goto out; + } + ++ if (enable) ++ st_lsm6dsx_update_samples_to_discard(sensor); ++ + err = st_lsm6dsx_device_set_enable(sensor, enable); + if (err < 0) + goto out; +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +index dd674f3119ad2..f4872860cb458 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +@@ -622,6 +622,24 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { + .fs_len = 4, + }, + }, ++ .samples_to_discard = { ++ [ST_LSM6DSX_ID_ACC] = { ++ .val[0] = { 12500, 1 }, ++ .val[1] = { 26000, 1 }, ++ .val[2] = { 52000, 1 }, ++ .val[3] = { 104000, 2 }, ++ .val[4] = { 208000, 2 }, ++ .val[5] = { 416000, 2 }, ++ }, ++ [ST_LSM6DSX_ID_GYRO] = { ++ .val[0] = { 12500, 2 }, ++ .val[1] = { 26000, 5 }, ++ .val[2] = { 52000, 7 }, ++ .val[3] = { 104000, 12 }, ++ .val[4] = { 208000, 20 }, ++ .val[5] = { 416000, 36 }, ++ }, ++ }, + .irq_config = { + .irq1 = { + .addr = 0x0d, +-- +2.51.0 + diff --git a/queue-5.15/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-5.15/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..f6de15e530 --- /dev/null +++ b/queue-5.15/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From d1fbda924618c238443e06a113dc5d4ff2eed6b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index d448c802572eb..5fce038b61e03 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -348,7 +348,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-5.15/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch b/queue-5.15/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch new file mode 100644 index 0000000000..f0c8e87e89 --- /dev/null +++ b/queue-5.15/iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch @@ -0,0 +1,105 @@ +From 09686441fa5b66a2d40ec8ee64a9c9534a5c2768 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Oct 2022 13:07:26 +0200 +Subject: iio: imu: st_lsm6dsx: introduce st_lsm6dsx_device_set_enable routine + +From: Lorenzo Bianconi + +[ Upstream commit cd83c5c10036a2a156d725725daf3409832c8a24 ] + +Introduce st_lsm6dsx_device_set_enable utility routine and remove +duplicated code used to enable/disable sensors + +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/e3fbe5d4a3bed41130908669f745f78c8505cf47.1665399959.git.lorenzo@kernel.org +Signed-off-by: Jonathan Cameron +Stable-dep-of: c6d702f2b771 ("iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member") +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 11 +++++++++++ + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 14 +++----------- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 14 ++------------ + 3 files changed, 16 insertions(+), 23 deletions(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 72abb5c62e4a9..6a6e963fe9731 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -505,6 +505,17 @@ st_lsm6dsx_get_mount_matrix(const struct iio_dev *iio_dev, + return &hw->orientation; + } + ++static inline int ++st_lsm6dsx_device_set_enable(struct st_lsm6dsx_sensor *sensor, bool enable) ++{ ++ if (sensor->id == ST_LSM6DSX_ID_EXT0 || ++ sensor->id == ST_LSM6DSX_ID_EXT1 || ++ sensor->id == ST_LSM6DSX_ID_EXT2) ++ return st_lsm6dsx_shub_set_enable(sensor, enable); ++ ++ return st_lsm6dsx_sensor_set_enable(sensor, enable); ++} ++ + static const + struct iio_chan_spec_ext_info __maybe_unused st_lsm6dsx_accel_ext_info[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_lsm6dsx_get_mount_matrix), +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +index e78b699a044ed..9ebaf73561336 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +@@ -678,17 +678,9 @@ int st_lsm6dsx_update_fifo(struct st_lsm6dsx_sensor *sensor, bool enable) + goto out; + } + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) { +- err = st_lsm6dsx_shub_set_enable(sensor, enable); +- if (err < 0) +- goto out; +- } else { +- err = st_lsm6dsx_sensor_set_enable(sensor, enable); +- if (err < 0) +- goto out; +- } ++ err = st_lsm6dsx_device_set_enable(sensor, enable); ++ if (err < 0) ++ goto out; + + err = st_lsm6dsx_set_fifo_odr(sensor, enable); + if (err < 0) +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +index a778aceba3b10..dd674f3119ad2 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +@@ -2304,12 +2304,7 @@ static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) + continue; + } + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) +- err = st_lsm6dsx_shub_set_enable(sensor, false); +- else +- err = st_lsm6dsx_sensor_set_enable(sensor, false); ++ err = st_lsm6dsx_device_set_enable(sensor, false); + if (err < 0) + return err; + +@@ -2340,12 +2335,7 @@ static int __maybe_unused st_lsm6dsx_resume(struct device *dev) + if (!(hw->suspend_mask & BIT(sensor->id))) + continue; + +- if (sensor->id == ST_LSM6DSX_ID_EXT0 || +- sensor->id == ST_LSM6DSX_ID_EXT1 || +- sensor->id == ST_LSM6DSX_ID_EXT2) +- err = st_lsm6dsx_shub_set_enable(sensor, true); +- else +- err = st_lsm6dsx_sensor_set_enable(sensor, true); ++ err = st_lsm6dsx_device_set_enable(sensor, true); + if (err < 0) + return err; + +-- +2.51.0 + diff --git a/queue-5.15/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-5.15/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..1e5b8ed280 --- /dev/null +++ b/queue-5.15/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From e35013314607292386f184e522f24a4f2bc1e379 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 6beef8ce311e0..8936e08711c25 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -626,7 +626,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-5.15/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-5.15/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..22d0035dfb --- /dev/null +++ b/queue-5.15/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From 3aac4ebbd2ed341554715da1a0c53b8f566f6e3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index b987074f80965..ee9c398dd8f25 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -785,6 +785,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 7d2c21c3cfd4a..a7d11b82fe64d 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -541,8 +541,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -551,6 +554,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-5.15/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-5.15/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..3d77f12f00 --- /dev/null +++ b/queue-5.15/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From f09495edcda413e729bdedf07531985ce105902a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index da249140ed2a1..d145e0df01a98 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -263,17 +263,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -296,6 +298,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-5.15/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-5.15/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..625be76ec0 --- /dev/null +++ b/queue-5.15/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From 54831ec37ef7a4845937cd4b866dbd5f66658b68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-5.15/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch b/queue-5.15/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch new file mode 100644 index 0000000000..40beac6627 --- /dev/null +++ b/queue-5.15/kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch @@ -0,0 +1,123 @@ +From e8d419cf80f27fa61db17ad5c4e902e43c8442d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 17:03:41 +0200 +Subject: kmsan: introduce __no_sanitize_memory and __no_kmsan_checks + +From: Alexander Potapenko + +[ Upstream commit 9b448bc25b776daab3215393c3ce6953dd3bb8ad ] + +__no_sanitize_memory is a function attribute that instructs KMSAN to skip +a function during instrumentation. This is needed to e.g. implement the +noinstr functions. + +__no_kmsan_checks is a function attribute that makes KMSAN ignore the +uninitialized values coming from the function's inputs, and initialize the +function's outputs. + +Functions marked with this attribute can't be inlined into functions not +marked with it, and vice versa. This behavior is overridden by +__always_inline. + +__SANITIZE_MEMORY__ is a macro that's defined iff the file is instrumented +with KMSAN. This is not the same as CONFIG_KMSAN, which is defined for +every file. + +Link: https://lkml.kernel.org/r/20220915150417.722975-8-glider@google.com +Signed-off-by: Alexander Potapenko +Reviewed-by: Marco Elver +Cc: Alexander Viro +Cc: Alexei Starovoitov +Cc: Andrey Konovalov +Cc: Andrey Konovalov +Cc: Andy Lutomirski +Cc: Arnd Bergmann +Cc: Borislav Petkov +Cc: Christoph Hellwig +Cc: Christoph Lameter +Cc: David Rientjes +Cc: Dmitry Vyukov +Cc: Eric Biggers +Cc: Eric Biggers +Cc: Eric Dumazet +Cc: Greg Kroah-Hartman +Cc: Herbert Xu +Cc: Ilya Leoshkevich +Cc: Ingo Molnar +Cc: Jens Axboe +Cc: Joonsoo Kim +Cc: Kees Cook +Cc: Mark Rutland +Cc: Matthew Wilcox +Cc: Michael S. Tsirkin +Cc: Pekka Enberg +Cc: Peter Zijlstra +Cc: Petr Mladek +Cc: Stephen Rothwell +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Vasily Gorbik +Cc: Vegard Nossum +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + include/linux/compiler-clang.h | 23 +++++++++++++++++++++++ + include/linux/compiler-gcc.h | 6 ++++++ + 2 files changed, 29 insertions(+) + +diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h +index 29be8ad715498..3397f6809c869 100644 +--- a/include/linux/compiler-clang.h ++++ b/include/linux/compiler-clang.h +@@ -79,6 +79,29 @@ + #define __no_sanitize_undefined + #endif + ++#if __has_feature(memory_sanitizer) ++#define __SANITIZE_MEMORY__ ++/* ++ * Unlike other sanitizers, KMSAN still inserts code into functions marked with ++ * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation ++ * provides the behavior consistent with other __no_sanitize_ attributes, ++ * guaranteeing that __no_sanitize_memory functions remain uninstrumented. ++ */ ++#define __no_sanitize_memory __disable_sanitizer_instrumentation ++ ++/* ++ * The __no_kmsan_checks attribute ensures that a function does not produce ++ * false positive reports by: ++ * - initializing all local variables and memory stores in this function; ++ * - skipping all shadow checks; ++ * - passing initialized arguments to this function's callees. ++ */ ++#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory"))) ++#else ++#define __no_sanitize_memory ++#define __no_kmsan_checks ++#endif ++ + /* + * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together + * with no_sanitize("coverage"). Prior versions of Clang support coverage +diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h +index 06c1cf2ab0244..64e20878af4d0 100644 +--- a/include/linux/compiler-gcc.h ++++ b/include/linux/compiler-gcc.h +@@ -131,6 +131,12 @@ + #define __SANITIZE_ADDRESS__ + #endif + ++/* ++ * GCC does not support KMSAN. ++ */ ++#define __no_sanitize_memory ++#define __no_kmsan_checks ++ + /* + * Turn individual warnings and errors on and off locally, depending + * on version. +-- +2.51.0 + diff --git a/queue-5.15/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-5.15/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..c5b44e815d --- /dev/null +++ b/queue-5.15/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From 66ba6977ec1d7dd1a2eb0ac882d289dd0b189a0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index 6692de0af68f1..ea0801b9cb010 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-5.15/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-5.15/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..f008a0ca4c --- /dev/null +++ b/queue-5.15/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From 7c2eb1056cdc81e9924d4ae88c8a84ae7cce88f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index e46eb93c115dd..fc1cf66fffdb3 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1889,9 +1889,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1957,6 +1954,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-5.15/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-5.15/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..b0bab6dd1d --- /dev/null +++ b/queue-5.15/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From fd3302d00b6b44895d29e91bbec70bb3b31f5482 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index 28b8581b44dda..b622df9f4b231 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -186,13 +186,14 @@ static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-5.15/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-5.15/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..69c34f9b01 --- /dev/null +++ b/queue-5.15/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From 6ec845c5a4d3ee600269a02393af118cb66cd3af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index c3bcbd8905c6c..a520890090ba4 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.15/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-5.15/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..40b456b069 --- /dev/null +++ b/queue-5.15/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From be0f0711a110b634366a77dd1b8eac38ebe934fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index 83f3ffbdbb4ca..1129f4ea54529 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -262,6 +262,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.15/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-5.15/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..114c42c521 --- /dev/null +++ b/queue-5.15/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 02192a062fa39ec7f7674dd6c9d9400b32c67ba7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 2924919da991a..e1daed7edc841 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -206,6 +206,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.15/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-5.15/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..273ba14e5e --- /dev/null +++ b/queue-5.15/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From a285dbe134134fbab438a1e11a3e62a846839c15 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index bde65af72feda..0776af7f74d94 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -1045,8 +1045,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-5.15/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-5.15/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..6fa4c4b26e --- /dev/null +++ b/queue-5.15/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From 1539c5a05bc7a221faf713f62c61b48ea868d057 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index ee063baed136c..5c39c9c653233 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -562,7 +562,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -578,7 +578,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -604,7 +604,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-5.15/nbd-clean-up-return-value-checking-of-sock_xmit.patch b/queue-5.15/nbd-clean-up-return-value-checking-of-sock_xmit.patch new file mode 100644 index 0000000000..9c533338ec --- /dev/null +++ b/queue-5.15/nbd-clean-up-return-value-checking-of-sock_xmit.patch @@ -0,0 +1,85 @@ +From df510c263ec6eb194a7a0f1c3c98c7fc8ffe812b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 17:33:48 +0800 +Subject: nbd: clean up return value checking of sock_xmit() + +From: Yu Kuai + +[ Upstream commit f52c0e08237e7864a44311fc78bc9bf2e045611b ] + +Check if sock_xmit() return 0 is useless because it'll never return +0, comment it and remove such checkings. + +Signed-off-by: Yu Kuai +Reviewed-by: Ming Lei +Reviewed-by: Josef Bacik +Link: https://lore.kernel.org/r/20210916093350.1410403-6-yukuai3@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 9517b82d8d42 ("nbd: defer config put in recv_work") +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 13 +++++++------ + 1 file changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index eca713f87614f..3f5c5e122bf78 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -487,7 +487,8 @@ static enum blk_eh_timer_return nbd_xmit_timeout(struct request *req, + } + + /* +- * Send or receive packet. ++ * Send or receive packet. Return a positive value on success and ++ * negtive value on failue, and never return 0. + */ + static int sock_xmit(struct nbd_device *nbd, int index, int send, + struct iov_iter *iter, int msg_flags, int *sent) +@@ -613,7 +614,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + result = sock_xmit(nbd, index, 1, &from, + (type == NBD_CMD_WRITE) ? MSG_MORE : 0, &sent); + trace_nbd_header_sent(req, handle); +- if (result <= 0) { ++ if (result < 0) { + if (was_interrupted(result)) { + /* If we havne't sent anything we can just return BUSY, + * however if we have sent something we need to make +@@ -657,7 +658,7 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + skip = 0; + } + result = sock_xmit(nbd, index, 1, &from, flags, &sent); +- if (result <= 0) { ++ if (result < 0) { + if (was_interrupted(result)) { + /* We've already sent the header, we + * have no choice but to set pending and +@@ -709,7 +710,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + reply.magic = 0; + iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); +- if (result <= 0) { ++ if (result < 0) { + if (!nbd_disconnected(config)) + dev_err(disk_to_dev(nbd->disk), + "Receive control failed (result %d)\n", result); +@@ -770,7 +771,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + rq_for_each_segment(bvec, req, iter) { + iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); +- if (result <= 0) { ++ if (result < 0) { + dev_err(disk_to_dev(nbd->disk), "Receive data failed (result %d)\n", + result); + /* +@@ -1216,7 +1217,7 @@ static void send_disconnects(struct nbd_device *nbd) + iov_iter_kvec(&from, WRITE, &iov, 1, sizeof(request)); + mutex_lock(&nsock->tx_lock); + ret = sock_xmit(nbd, i, 1, &from, 0, NULL); +- if (ret <= 0) ++ if (ret < 0) + dev_err(disk_to_dev(nbd->disk), + "Send disconnect failed %d\n", ret); + mutex_unlock(&nsock->tx_lock); +-- +2.51.0 + diff --git a/queue-5.15/nbd-defer-config-put-in-recv_work.patch b/queue-5.15/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..d7bd2c6da6 --- /dev/null +++ b/queue-5.15/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From 2b10bb2108b85ad6f7292d5df41aeac997a7e6d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index eb37427a3c019..ae89f6124cc6b 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -836,9 +836,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-5.15/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-5.15/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..edbda17a9c --- /dev/null +++ b/queue-5.15/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From 0f102078821de0000349bc8b4c4d8b62b56387a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index ae89f6124cc6b..79b0056edbafe 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2045,12 +2045,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-5.15/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch b/queue-5.15/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch new file mode 100644 index 0000000000..877643f6ac --- /dev/null +++ b/queue-5.15/nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch @@ -0,0 +1,163 @@ +From 93d3a3fbd814dd54b8b215026071687c66e7d15b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Sep 2021 17:33:49 +0800 +Subject: nbd: partition nbd_read_stat() into nbd_read_reply() and + nbd_handle_reply() + +From: Yu Kuai + +[ Upstream commit 3fe1db626a56cdf259c348404f2c5429e2f065a1 ] + +Prepare to fix uaf in nbd_read_stat(), no functional changes. + +Signed-off-by: Yu Kuai +Reviewed-by: Ming Lei +Reviewed-by: Josef Bacik +Link: https://lore.kernel.org/r/20210916093350.1410403-7-yukuai3@huawei.com +Signed-off-by: Jens Axboe +Stable-dep-of: 9517b82d8d42 ("nbd: defer config put in recv_work") +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 74 +++++++++++++++++++++++++++------------------ + 1 file changed, 44 insertions(+), 30 deletions(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 3f5c5e122bf78..eb37427a3c019 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -692,38 +692,45 @@ static int nbd_send_cmd(struct nbd_device *nbd, struct nbd_cmd *cmd, int index) + return 0; + } + +-/* NULL returned = something went wrong, inform userspace */ +-static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) ++static int nbd_read_reply(struct nbd_device *nbd, int index, ++ struct nbd_reply *reply) + { +- struct nbd_config *config = nbd->config; +- int result; +- struct nbd_reply reply; +- struct nbd_cmd *cmd; +- struct request *req = NULL; +- u64 handle; +- u16 hwq; +- u32 tag; +- struct kvec iov = {.iov_base = &reply, .iov_len = sizeof(reply)}; ++ struct kvec iov = {.iov_base = reply, .iov_len = sizeof(*reply)}; + struct iov_iter to; +- int ret = 0; ++ int result; + +- reply.magic = 0; +- iov_iter_kvec(&to, READ, &iov, 1, sizeof(reply)); ++ reply->magic = 0; ++ iov_iter_kvec(&to, READ, &iov, 1, sizeof(*reply)); + result = sock_xmit(nbd, index, 0, &to, MSG_WAITALL, NULL); + if (result < 0) { +- if (!nbd_disconnected(config)) ++ if (!nbd_disconnected(nbd->config)) + dev_err(disk_to_dev(nbd->disk), + "Receive control failed (result %d)\n", result); +- return ERR_PTR(result); ++ return result; + } + +- if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { ++ if (ntohl(reply->magic) != NBD_REPLY_MAGIC) { + dev_err(disk_to_dev(nbd->disk), "Wrong magic (0x%lx)\n", +- (unsigned long)ntohl(reply.magic)); +- return ERR_PTR(-EPROTO); ++ (unsigned long)ntohl(reply->magic)); ++ return -EPROTO; + } + +- memcpy(&handle, reply.handle, sizeof(handle)); ++ return 0; ++} ++ ++/* NULL returned = something went wrong, inform userspace */ ++static struct nbd_cmd *nbd_handle_reply(struct nbd_device *nbd, int index, ++ struct nbd_reply *reply) ++{ ++ int result; ++ struct nbd_cmd *cmd; ++ struct request *req = NULL; ++ u64 handle; ++ u16 hwq; ++ u32 tag; ++ int ret = 0; ++ ++ memcpy(&handle, reply->handle, sizeof(handle)); + tag = nbd_handle_to_tag(handle); + hwq = blk_mq_unique_tag_to_hwq(tag); + if (hwq < nbd->tag_set.nr_hw_queues) +@@ -756,9 +763,9 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + ret = -ENOENT; + goto out; + } +- if (ntohl(reply.error)) { ++ if (ntohl(reply->error)) { + dev_err(disk_to_dev(nbd->disk), "Other side returned error (%d)\n", +- ntohl(reply.error)); ++ ntohl(reply->error)); + cmd->status = BLK_STS_IOERR; + goto out; + } +@@ -767,6 +774,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + if (rq_data_dir(req) != WRITE) { + struct req_iterator iter; + struct bio_vec bvec; ++ struct iov_iter to; + + rq_for_each_segment(bvec, req, iter) { + iov_iter_bvec(&to, READ, &bvec, 1, bvec.bv_len); +@@ -780,7 +788,7 @@ static struct nbd_cmd *nbd_read_stat(struct nbd_device *nbd, int index) + * and let the timeout stuff handle resubmitting + * this request onto another connection. + */ +- if (nbd_disconnected(config)) { ++ if (nbd_disconnected(nbd->config)) { + cmd->status = BLK_STS_IOERR; + goto out; + } +@@ -804,24 +812,30 @@ static void recv_work(struct work_struct *work) + work); + struct nbd_device *nbd = args->nbd; + struct nbd_config *config = nbd->config; ++ struct nbd_sock *nsock; + struct nbd_cmd *cmd; + struct request *rq; + + while (1) { +- cmd = nbd_read_stat(nbd, args->index); +- if (IS_ERR(cmd)) { +- struct nbd_sock *nsock = config->socks[args->index]; ++ struct nbd_reply reply; + +- mutex_lock(&nsock->tx_lock); +- nbd_mark_nsock_dead(nbd, nsock, 1); +- mutex_unlock(&nsock->tx_lock); ++ if (nbd_read_reply(nbd, args->index, &reply)) ++ break; ++ ++ cmd = nbd_handle_reply(nbd, args->index, &reply); ++ if (IS_ERR(cmd)) + break; +- } + + rq = blk_mq_rq_from_pdu(cmd); + if (likely(!blk_should_fake_timeout(rq->q))) + blk_mq_complete_request(rq); + } ++ ++ nsock = config->socks[args->index]; ++ mutex_lock(&nsock->tx_lock); ++ nbd_mark_nsock_dead(nbd, nsock, 1); ++ mutex_unlock(&nsock->tx_lock); ++ + nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); +-- +2.51.0 + diff --git a/queue-5.15/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-5.15/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..dc79c0a078 --- /dev/null +++ b/queue-5.15/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From 6b7af10ab53e00d5e2f9b50cce088e0b6d95c5e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 73b840762afb2..cfeda7b50cc2e 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1608,7 +1608,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1754,14 +1753,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1834,6 +1833,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1844,13 +1845,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1859,11 +1860,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1938,24 +1939,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-5.15/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-5.15/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..4c586d4ab2 --- /dev/null +++ b/queue-5.15/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From 564e84a13750ccfad55e80e310aeb76df3f25f23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 973c60e013344..e056b512c1277 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -4983,10 +4983,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-5.15/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-5.15/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..f8e509485c --- /dev/null +++ b/queue-5.15/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From 1a86f14ec29ccd0a3d98354d09d458cbdc08b724 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 41d04fa12f67d..e1d7231b87748 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -140,12 +140,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-5.15/netfilter-nf_conncount-reduce-unnecessary-gc.patch b/queue-5.15/netfilter-nf_conncount-reduce-unnecessary-gc.patch new file mode 100644 index 0000000000..f134af0637 --- /dev/null +++ b/queue-5.15/netfilter-nf_conncount-reduce-unnecessary-gc.patch @@ -0,0 +1,118 @@ +From 96d9ebd461c7397120ff7e4cdc0232d9308817e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 May 2022 08:35:59 -0700 +Subject: netfilter: nf_conncount: reduce unnecessary GC + +From: William Tu + +[ Upstream commit d265929930e2ffafc744c0ae05fb70acd53be1ee ] + +Currently nf_conncount can trigger garbage collection (GC) +at multiple places. Each GC process takes a spin_lock_bh +to traverse the nf_conncount_list. We found that when testing +port scanning use two parallel nmap, because the number of +connection increase fast, the nf_conncount_count and its +subsequent call to __nf_conncount_add take too much time, +causing several CPU lockup. This happens when user set the +conntrack limit to +20,000, because the larger the limit, +the longer the list that GC has to traverse. + +The patch mitigate the performance issue by avoiding unnecessary +GC with a timestamp. Whenever nf_conncount has done a GC, +a timestamp is updated, and beforce the next time GC is +triggered, we make sure it's more than a jiffies. +By doin this we can greatly reduce the CPU cycles and +avoid the softirq lockup. + +To reproduce it in OVS, +$ ovs-appctl dpctl/ct-set-limits zone=1,limit=20000 +$ ovs-appctl dpctl/ct-get-limits + +At another machine, runs two nmap +$ nmap -p1- +$ nmap -p1- + +Signed-off-by: William Tu +Co-authored-by: Yifeng Sun +Reported-by: Greg Rose +Suggested-by: Florian Westphal +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 69894e5b4c5e ("netfilter: nft_connlimit: update the count if add was skipped") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 1 + + net/netfilter/nf_conncount.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index 9645b47fa7e41..e227d997fc716 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -10,6 +10,7 @@ struct nf_conncount_data; + + struct nf_conncount_list { + spinlock_t list_lock; ++ u32 last_gc; /* jiffies at most recent gc */ + struct list_head head; /* connections with the same filtering key */ + unsigned int count; /* length of list */ + }; +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index a66a27fe7f458..ee808b018e4e1 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -132,6 +132,9 @@ static int __nf_conncount_add(struct net *net, + struct nf_conn *found_ct; + unsigned int collect = 0; + ++ if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) ++ goto add_new_node; ++ + /* check the saved connections */ + list_for_each_entry_safe(conn, conn_n, &list->head, node) { + if (collect > CONNCOUNT_GC_MAX_NODES) +@@ -177,6 +180,7 @@ static int __nf_conncount_add(struct net *net, + nf_ct_put(found_ct); + } + ++add_new_node: + if (WARN_ON_ONCE(list->count > INT_MAX)) + return -EOVERFLOW; + +@@ -190,6 +194,7 @@ static int __nf_conncount_add(struct net *net, + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; ++ list->last_gc = (u32)jiffies; + return 0; + } + +@@ -214,6 +219,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list) + spin_lock_init(&list->list_lock); + INIT_LIST_HEAD(&list->head); + list->count = 0; ++ list->last_gc = (u32)jiffies; + } + EXPORT_SYMBOL_GPL(nf_conncount_list_init); + +@@ -227,6 +233,10 @@ bool nf_conncount_gc_list(struct net *net, + unsigned int collected = 0; + bool ret = false; + ++ /* don't bother if we just did GC */ ++ if (time_is_after_eq_jiffies((unsigned long)READ_ONCE(list->last_gc))) ++ return false; ++ + /* don't bother if other cpu is already doing GC */ + if (!spin_trylock(&list->list_lock)) + return false; +@@ -258,6 +268,7 @@ bool nf_conncount_gc_list(struct net *net, + + if (!list->count) + ret = true; ++ list->last_gc = (u32)jiffies; + spin_unlock(&list->list_lock); + + return ret; +-- +2.51.0 + diff --git a/queue-5.15/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-5.15/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..7aef03df68 --- /dev/null +++ b/queue-5.15/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,504 @@ +From 83672399c5e5c5efd212dac6b421b40e5f6ba720 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Stable-dep-of: 69894e5b4c5e ("netfilter: nft_connlimit: update the count if add was skipped") +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index e227d997fc716..115bb7e572f7d 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family + void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index ee808b018e4e1..5fdf451f2322c 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen) +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 403fffa14fa3b..d7dbc1ce6bd36 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index 9943a2bf7a7b8..489f101875584 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 85a338b681780..4c5480a345c9f 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -1161,8 +1161,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -1175,8 +1175,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -1205,8 +1206,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -2058,8 +2058,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-5.15/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-5.15/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..f15fbccf06 --- /dev/null +++ b/queue-5.15/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From cd8e94c27ce6fb685cb2406bd6d6f6ede70acbc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 5fdf451f2322c..3e8828bdcd1b3 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if (time_is_after_eq_jiffies((unsigned long)list->last_gc)) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index d7dbc1ce6bd36..ef5099441a822 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-5.15/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-5.15/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..8f0ccc9e67 --- /dev/null +++ b/queue-5.15/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 43797a7987c29ecf6f7b0604c9fbfe8121c25711 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index ba8961e72feaa..735fd1cdf4771 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -27,6 +27,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -57,7 +58,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-5.15/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-5.15/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..23ae53e1d7 --- /dev/null +++ b/queue-5.15/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From d17887338e07097a70d005a3223a592eee3e37bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 019a98e300dcf..7797e35364495 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1696,6 +1696,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-5.15/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-5.15/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..c813436c54 --- /dev/null +++ b/queue-5.15/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From 06bca1695940495e4c614c3010d06f8d3b565c2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index abf28c0db71a3..c82398194cd10 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1343,7 +1343,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-5.15/ntfs3-init-run-lock-for-extend-inode.patch b/queue-5.15/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..a2dc3f548c --- /dev/null +++ b/queue-5.15/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From a3b7c2ccee4a6223f382f3ac51a03c28b72aeec7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 7797e35364495..0f4e166112de1 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -457,6 +457,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-5.15/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-5.15/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..252da6332b --- /dev/null +++ b/queue-5.15/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From d0f2c3f0fc28ad9be0390a948ecf631dc9d8c2d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 866d57dfe9f74..1ac42064657d5 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-5.15/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-5.15/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..2d47120c5b --- /dev/null +++ b/queue-5.15/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From e98e4d8dab7c660fd2d10551db38fdd48afd0a76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index 8ba2392926346..5960ae40b0f2d 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -52,7 +52,7 @@ + #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-5.15/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-5.15/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..5f363599c6 --- /dev/null +++ b/queue-5.15/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From cb9f52962ae52e0f4530b1a5709e34ef7bd01d5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index c277f76276ab1..ad399e9ce5dc5 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1328,6 +1328,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-5.15/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-5.15/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..f1eedc55c5 --- /dev/null +++ b/queue-5.15/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From 101b102dca7855905a532c7f7ae70fc55eebbfc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 80c54196e0e4f..b48d237124e12 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -893,11 +893,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + if (ndso == NULL) +-- +2.51.0 + diff --git a/queue-5.15/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-5.15/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..51dc155810 --- /dev/null +++ b/queue-5.15/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From 74f6d1126f9dc611fb8f27a8e41441d231331b85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 767c60af13be3..589c850fe4b00 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3639,7 +3639,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-5.15/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-5.15/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..8467e48eea --- /dev/null +++ b/queue-5.15/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From fb51b22201766f512c8e5770103ce1d8f6faf779 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index 982e73adf2bcf..acc9e1a266314 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2560,7 +2560,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2581,12 +2581,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-5.15/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-5.15/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..9f6e39e4e4 --- /dev/null +++ b/queue-5.15/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From cad499917a68e76f4d0b28f873c86b357b561694 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index b81297084f097..0659cd3aa3a5a 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -490,7 +490,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -554,9 +555,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-5.15/pinctrl-single-fix-pin_config_bias_disable-handling.patch b/queue-5.15/pinctrl-single-fix-pin_config_bias_disable-handling.patch new file mode 100644 index 0000000000..d434fd86f9 --- /dev/null +++ b/queue-5.15/pinctrl-single-fix-pin_config_bias_disable-handling.patch @@ -0,0 +1,95 @@ +From c423c2b83a54c04cf760f34fb9b33887d687ac96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 12:06:34 +0100 +Subject: pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling + +From: Matthijs Kooijman + +[ Upstream commit b5fe46efc147516a908d2d31bf40eb858ab76d51 ] + +The pinctrl-single driver handles pin_config_set by looking up the +requested setting in a DT-defined lookup table, which defines what bits +correspond to each setting. There is no way to add +PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead +code to disable the bias by applying the disable values of both the +pullup and pulldown entries in the table. + +However, this code is inside the table-lookup loop, so it would only +execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, +which can never exist, so this code never runs. + +This commit lifts the offending code out of the loop, so it just +executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, +skippipng the table lookup loop. + +This also introduces a new `param` variable to make the code slightly +more readable. + +This bug seems to have existed when this code was first merged in commit +9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier +versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in +the lookup table, but that was removed, which is probably how this bug +was introduced. + +Signed-off-by: Matthijs Kooijman +Reviewed-by: Haojian Zhuang +Reviewed-by: Tony Lindgren +Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> +Signed-off-by: Linus Walleij +Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable") +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index a72911e8ea82d..b81297084f097 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -557,21 +557,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + unsigned offset = 0, shift = 0, i, data, ret; + u32 arg; + int j; ++ enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (j = 0; j < num_configs; j++) { ++ param = pinconf_to_config_param(configs[j]); ++ ++ /* BIAS_DISABLE has no entry in the func->conf table */ ++ if (param == PIN_CONFIG_BIAS_DISABLE) { ++ /* This just disables all bias entries */ ++ pcs_pinconf_clear_bias(pctldev, pin); ++ continue; ++ } ++ + for (i = 0; i < func->nconfs; i++) { +- if (pinconf_to_config_param(configs[j]) +- != func->conf[i].param) ++ if (param != func->conf[i].param) + continue; + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset); + arg = pinconf_to_config_argument(configs[j]); +- switch (func->conf[i].param) { ++ switch (param) { + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_DRIVE_STRENGTH: +@@ -583,9 +592,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + data |= (arg << shift) & func->conf[i].mask; + break; + /* 4 parameters */ +- case PIN_CONFIG_BIAS_DISABLE: +- pcs_pinconf_clear_bias(pctldev, pin); +- break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (arg) { +-- +2.51.0 + diff --git a/queue-5.15/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-5.15/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..2556fdceef --- /dev/null +++ b/queue-5.15/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From d5d35567d61e490d22c88b28a0b40bce5227f795 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 821ec5a97551d..e8afed94fccc1 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1490,7 +1490,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-5.15/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-5.15/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..e6aa456b90 --- /dev/null +++ b/queue-5.15/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From 25a5b743bdc1120ddd49e7adf1059057014222a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9d1a7fbcaed42..50b9636945599 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -365,7 +365,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-5.15/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-5.15/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..20dc04690c --- /dev/null +++ b/queue-5.15/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From 6a0d29c7e977676ef4ac9ca7d75d8150164cf97f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 4cd2dd8700395..902e01a3fc730 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-5.15/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-5.15/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..add82f8be7 --- /dev/null +++ b/queue-5.15/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From 1436f1bc1cf572cbde397799d9d7e2c004137098 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index 3eb3c74e402b5..c23b2b0046970 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -314,10 +314,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -360,10 +359,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-5.15/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-5.15/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..707321d39f --- /dev/null +++ b/queue-5.15/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From dfd9b24dc148495860551d6d2f7ce2a3d239b63e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index c7f824d294b25..5e482b90c4007 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-5.15/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-5.15/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..3accfddf32 --- /dev/null +++ b/queue-5.15/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From 964bb0c61e463043925252be1976905eb9cbaae3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index 8d51efbe045dd..8628ee818da96 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-5.15/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-5.15/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..5de7c48a36 --- /dev/null +++ b/queue-5.15/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From fc775d164d88ba2b54783bfe9482b939b60821dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 50b8594be31d8..4541d63d57c40 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -35,29 +35,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return container_of(chip, struct bcm2835_pwm, chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -109,6 +86,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -126,8 +106,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + .owner = THIS_MODULE, + }; +-- +2.51.0 + diff --git a/queue-5.15/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-5.15/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..524f750b2e --- /dev/null +++ b/queue-5.15/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From 4db5d3434751bda7682c581042feb0957257e28f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index d8afdb8784c1c..c89dd30fa3dff 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-5.15/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-5.15/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..0643843f87 --- /dev/null +++ b/queue-5.15/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From 00e74c6427e4bb91738a818a3ca9f89b1ce00a46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index 6562592695b70..f4d5d1cee681f 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -507,12 +507,14 @@ enum irdma_status_code irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-5.15/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-5.15/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..3a5e2f688e --- /dev/null +++ b/queue-5.15/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From f1025bec91b9e4589503f3f761b9ee6f4e145ce4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index e6851cffa40af..e1c40776de440 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3354,11 +3354,13 @@ enum irdma_status_code irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3369,6 +3371,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-5.15/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-5.15/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..acbeb474bb --- /dev/null +++ b/queue-5.15/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From dee702e43eea63e4c7798932a12c13e5946c2ba8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 96fe7c97bc713..ec3ab8df32f7d 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1453,7 +1453,7 @@ static struct rtrs_srv *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-5.15/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-5.15/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..13a82c7c13 --- /dev/null +++ b/queue-5.15/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From 229500785e413b91f09e8289d0eb4010d1d92191 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index ed5d58baa1f75..6c5913a1a6821 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1616,6 +1616,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1635,11 +1637,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-5.15/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-5.15/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..55510a4530 --- /dev/null +++ b/queue-5.15/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From ebd2f69f65afbf1be1974e674fb576646ffa0769 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 6c5913a1a6821..af0218227a8c7 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1933,6 +1933,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1941,6 +1942,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2419,22 +2421,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2454,11 +2460,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-5.15/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-5.15/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..b5d5648807 --- /dev/null +++ b/queue-5.15/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From b6cce5999ec5845608bc02ce90126a0909a80507 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index cfd34ffcbb121..d900ef12ada43 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-5.15/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-5.15/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..8343dc813e --- /dev/null +++ b/queue-5.15/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From dc3acc7607428997c2668ee0b06cfb021e1e455c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 1dd6dd2ed7fbc..489dff1dd94ef 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -1873,15 +1873,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-5.15/s390-smp-fix-fallback-cpu-detection.patch b/queue-5.15/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..56ffaa893c --- /dev/null +++ b/queue-5.15/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From 500d0b26a7e86afa2e9dd230ee44d9324842eb93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 5c1fd147591cb..824941e3204d7 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -754,6 +754,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-5.15/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-5.15/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..7bdb490475 --- /dev/null +++ b/queue-5.15/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From 9418b55cd6f51aa43228104b01bbfd8bc2046426 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-5.15/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-5.15/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..9a94b4d06f --- /dev/null +++ b/queue-5.15/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From fd67924f11b652d0c7282fa9ac37f8a1d2e42680 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index 1ff9b8e85b09c..8ff92ab9b27b1 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1848,6 +1848,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-5.15/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-5.15/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..96d616c946 --- /dev/null +++ b/queue-5.15/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From ba81ec474ca42910bcc7239efb44fdc72d711cea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 73a9e7b0ecbc7..120c19e41012b 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2677,7 +2677,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-5.15/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-5.15/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..22317b13da --- /dev/null +++ b/queue-5.15/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From a402bebff5e6f396a7d3e47d748c6c726bc72d71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 0aaea911b21ef..424af9d0434db 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1551,8 +1551,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5101,9 +5099,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Triggered when there are no references on the socket anymore */ +-- +2.51.0 + diff --git a/queue-5.15/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-5.15/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..d40df29129 --- /dev/null +++ b/queue-5.15/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From d4170303df1d650aafdab14213ed013a9319a3b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 7b1343f70e65a..ab5fedc5741e8 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -138,6 +138,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-5.15/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-5.15/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..5a01a3b477 --- /dev/null +++ b/queue-5.15/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From af86f24d62ba46829620074867814dc04170cf99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 4a17253413a3a..67cf46056ffe9 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-5.15/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-5.15/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..de5fe4ac3f --- /dev/null +++ b/queue-5.15/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From aa7b1432b6cea05c30444aba516d84149f7e288d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 12c4f45cee1a8..4a17253413a3a 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index c2c3a660de..8fb64ae9b5 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -32,3 +32,137 @@ comedi-multiq3-sanitize-config-options-in-multiq3_attach.patch comedi-check-device-s-attached-status-in-compat-ioctls.patch staging-rtl8723bs-fix-stack-buffer-overflow-in-onassocreq-ie-parsing.patch staging-rtl8723bs-fix-out-of-bounds-read-in-onbeacon-esr-ie-parsing.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +iio-imu-st_lsm6dsx-introduce-st_lsm6dsx_device_set_e.patch +iio-imu-st_lsm6dsx-discard-samples-during-filters-se.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +s390-smp-fix-fallback-cpu-detection.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +compiler-gcc.h-define-__sanitize_address__-under-hwa.patch +kmsan-introduce-__no_sanitize_memory-and-__no_kmsan_.patch +x86-kmsan-don-t-instrument-stack-walking-functions.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +i3c-remove-i2c-board-info-from-i2c_dev_desc.patch +i3c-support-dynamically-added-i2c-devices.patch +i3c-allow-of-alias-based-persistent-bus-numbering.patch +i3c-master-inherit-dma-masks-and-parameters-from-par.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +spi-tegra210-quad-use-device_reset-method.patch +spi-tegra210-quad-add-new-chips-to-compatible.patch +spi-tegra210-quad-combined-sequence-mode.patch +spi-tegra210-quad-modify-chip-select-cs-deactivation.patch +spi-tegra210-quad-fix-timeout-handling.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +ext4-minor-defrag-code-improvements.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +nbd-clean-up-return-value-checking-of-sock_xmit.patch +nbd-partition-nbd_read_stat-into-nbd_read_reply-and-.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +ntfs3-init-run-lock-for-extend-inode.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +coresight-etm4x-save-restore-trfcr_el1.patch +coresight-etm4x-use-trace-filtering-controls-dynamic.patch +coresight-etm4x-add-isb-before-reading-the-trcstatr.patch +coresight-etm4x-extract-the-trace-unit-controlling.patch +coresight-etm4x-add-context-synchronization-before-e.patch +clk-renesas-r9a06g032-export-function-to-set-dmamux.patch +soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +fs-ntfs3-remove-unused-mi_mark_free.patch +fs-ntfs3-add-new-argument-is_mft-to-ntfs_mark_rec_fr.patch +fs-ntfs3-make-ni_ins_new_attr-return-error.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led_bl-take-led_access-lock-when-required.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +asoc-fsl_xcvr-add-counter-registers.patch +asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ext4-remove-unused-return-value-of-__mb_check_buddy.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +vdpa-introduce-and-use-vdpa-device-get-set-config-he.patch +vdpa-introduce-query-of-device-config-layout.patch +vdpa-sync-calls-set-get-config-status-with-cf_mutex.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-virtqueue_set_affinity-docs.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-reduce-unnecessary-gc.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +pinctrl-single-fix-pin_config_bias_disable-handling.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch diff --git a/queue-5.15/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-5.15/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..abaeb5ea15 --- /dev/null +++ b/queue-5.15/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From b3ddca624534ecfa30a674390fd7873b9e7ae53b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 1c62b3db50045..6075c43999675 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3551,8 +3551,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3563,28 +3563,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + if (strcmp(name, "current") != 0) + return -EINVAL; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-5.15/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch b/queue-5.15/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch new file mode 100644 index 0000000000..cd0d5726bf --- /dev/null +++ b/queue-5.15/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch @@ -0,0 +1,85 @@ +From 2bcf0fd9833c87ff340cba986995cf3b3f230dc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 16:22:54 +0100 +Subject: soc: renesas: r9a06g032-sysctrl: Handle h2mode setting based on USBF + presence + +From: Herve Codina + +[ Upstream commit e9fee814b054e4f6f2faf3d9c1944869fe41c9dd ] + +The CFG_USB[H2MODE] allows to switch the USB configuration. The +configuration supported are: + - One host and one device +or + - Two hosts + +Set CFG_USB[H2MODE] based on the USBF controller (USB device) +availability. + +Signed-off-by: Herve Codina +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230105152257.310642-3-herve.codina@bootlin.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 28 ++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 9f42d46ce6192..e46280059db79 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -24,6 +24,8 @@ + #include + #include + ++#define R9A06G032_SYSCTRL_USB 0x00 ++#define R9A06G032_SYSCTRL_USB_H2MODE (1<<1) + #define R9A06G032_SYSCTRL_DMAMUX 0xA0 + + struct r9a06g032_gate { +@@ -919,6 +921,29 @@ static void r9a06g032_clocks_del_clk_provider(void *data) + of_clk_del_provider(data); + } + ++static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks) ++{ ++ struct device_node *usbf_np = NULL; ++ u32 usb; ++ ++ while ((usbf_np = of_find_compatible_node(usbf_np, NULL, ++ "renesas,rzn1-usbf"))) { ++ if (of_device_is_available(usbf_np)) ++ break; ++ } ++ ++ usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); ++ if (usbf_np) { ++ /* 1 host and 1 device mode */ ++ usb &= ~R9A06G032_SYSCTRL_USB_H2MODE; ++ of_node_put(usbf_np); ++ } else { ++ /* 2 hosts mode */ ++ usb |= R9A06G032_SYSCTRL_USB_H2MODE; ++ } ++ writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); ++} ++ + static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -948,6 +973,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + clocks->reg = of_iomap(np, 0); + if (WARN_ON(!clocks->reg)) + return -ENOMEM; ++ ++ r9a06g032_init_h2mode(clocks); ++ + for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { + const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; + const char *parent_name = d->source ? +-- +2.51.0 + diff --git a/queue-5.15/spi-tegra210-quad-add-new-chips-to-compatible.patch b/queue-5.15/spi-tegra210-quad-add-new-chips-to-compatible.patch new file mode 100644 index 0000000000..2239da323d --- /dev/null +++ b/queue-5.15/spi-tegra210-quad-add-new-chips-to-compatible.patch @@ -0,0 +1,82 @@ +From 724e1148b6fae4a72e136f5b2f16eaecce4972d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Feb 2022 23:26:09 +0530 +Subject: spi: tegra210-quad: add new chips to compatible + +From: Krishna Yarlagadda + +[ Upstream commit ea23f0e148b82e5bcbc6c814926f53133552f0f3 ] + +Add support for Tegra234 and soc data to select capabilities. + +Signed-off-by: Krishna Yarlagadda +Link: https://lore.kernel.org/r/20220222175611.58051-4-kyarlagadda@nvidia.com +Signed-off-by: Mark Brown +Stable-dep-of: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 33 ++++++++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index c3867c70c61d4..325ff5c1926c4 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -125,6 +125,10 @@ + #define QSPI_DMA_TIMEOUT (msecs_to_jiffies(1000)) + #define DEFAULT_QSPI_DMA_BUF_LEN (64 * 1024) + ++struct tegra_qspi_soc_data { ++ bool has_dma; ++}; ++ + struct tegra_qspi_client_data { + int tx_clk_tap_delay; + int rx_clk_tap_delay; +@@ -184,6 +188,7 @@ struct tegra_qspi { + u32 *tx_dma_buf; + dma_addr_t tx_dma_phys; + struct dma_async_tx_descriptor *tx_dma_desc; ++ const struct tegra_qspi_soc_data *soc_data; + }; + + static inline u32 tegra_qspi_readl(struct tegra_qspi *tqspi, unsigned long offset) +@@ -1199,10 +1204,32 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + return handle_dma_based_xfer(tqspi); + } + ++static struct tegra_qspi_soc_data tegra210_qspi_soc_data = { ++ .has_dma = true, ++}; ++ ++static struct tegra_qspi_soc_data tegra186_qspi_soc_data = { ++ .has_dma = true, ++}; ++ ++static struct tegra_qspi_soc_data tegra234_qspi_soc_data = { ++ .has_dma = false, ++}; ++ + static const struct of_device_id tegra_qspi_of_match[] = { +- { .compatible = "nvidia,tegra210-qspi", }, +- { .compatible = "nvidia,tegra186-qspi", }, +- { .compatible = "nvidia,tegra194-qspi", }, ++ { ++ .compatible = "nvidia,tegra210-qspi", ++ .data = &tegra210_qspi_soc_data, ++ }, { ++ .compatible = "nvidia,tegra186-qspi", ++ .data = &tegra186_qspi_soc_data, ++ }, { ++ .compatible = "nvidia,tegra194-qspi", ++ .data = &tegra186_qspi_soc_data, ++ }, { ++ .compatible = "nvidia,tegra234-qspi", ++ .data = &tegra234_qspi_soc_data, ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-5.15/spi-tegra210-quad-combined-sequence-mode.patch b/queue-5.15/spi-tegra210-quad-combined-sequence-mode.patch new file mode 100644 index 0000000000..459c610ea6 --- /dev/null +++ b/queue-5.15/spi-tegra210-quad-combined-sequence-mode.patch @@ -0,0 +1,346 @@ +From 2f24f749f3f18412cee40cab54e178a1fe1f32c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Mar 2022 22:25:18 +0530 +Subject: spi: tegra210-quad: combined sequence mode + +From: Krishna Yarlagadda + +[ Upstream commit 1b8342cc4a387933780c50f0cf51c94455be7d11 ] + +Add combined sequence mode supported by Tegra QSPI controller. +For commands which contain cmd, addr, data parts to it, controller +can accept all 3 transfers at once and avoid interrupt for each +transfer. This would improve read & write performance. + +Signed-off-by: Krishna Yarlagadda +Reported-by: kernel test robot +Reported-by: Dan Carpenter +Link: https://lore.kernel.org/r/20220307165519.38380-3-kyarlagadda@nvidia.com +Signed-off-by: Mark Brown +Stable-dep-of: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 238 +++++++++++++++++++++++++++++++- + 1 file changed, 233 insertions(+), 5 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 325ff5c1926c4..ff6a2c297b8af 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -119,14 +119,39 @@ + #define QSPI_NUM_DUMMY_CYCLE(x) (((x) & 0xff) << 0) + #define QSPI_DUMMY_CYCLES_MAX 0xff + ++#define QSPI_CMB_SEQ_CMD 0x19c ++#define QSPI_COMMAND_VALUE_SET(X) (((x) & 0xFF) << 0) ++ ++#define QSPI_CMB_SEQ_CMD_CFG 0x1a0 ++#define QSPI_COMMAND_X1_X2_X4(x) (((x) & 0x3) << 13) ++#define QSPI_COMMAND_X1_X2_X4_MASK (0x03 << 13) ++#define QSPI_COMMAND_SDR_DDR BIT(12) ++#define QSPI_COMMAND_SIZE_SET(x) (((x) & 0xFF) << 0) ++ ++#define QSPI_GLOBAL_CONFIG 0X1a4 ++#define QSPI_CMB_SEQ_EN BIT(0) ++ ++#define QSPI_CMB_SEQ_ADDR 0x1a8 ++#define QSPI_ADDRESS_VALUE_SET(X) (((x) & 0xFFFF) << 0) ++ ++#define QSPI_CMB_SEQ_ADDR_CFG 0x1ac ++#define QSPI_ADDRESS_X1_X2_X4(x) (((x) & 0x3) << 13) ++#define QSPI_ADDRESS_X1_X2_X4_MASK (0x03 << 13) ++#define QSPI_ADDRESS_SDR_DDR BIT(12) ++#define QSPI_ADDRESS_SIZE_SET(x) (((x) & 0xFF) << 0) ++ + #define DATA_DIR_TX BIT(0) + #define DATA_DIR_RX BIT(1) + + #define QSPI_DMA_TIMEOUT (msecs_to_jiffies(1000)) + #define DEFAULT_QSPI_DMA_BUF_LEN (64 * 1024) ++#define CMD_TRANSFER 0 ++#define ADDR_TRANSFER 1 ++#define DATA_TRANSFER 2 + + struct tegra_qspi_soc_data { + bool has_dma; ++ bool cmb_xfer_capable; + }; + + struct tegra_qspi_client_data { +@@ -918,7 +943,6 @@ static int tegra_qspi_setup(struct spi_device *spi) + cdata = tegra_qspi_parse_cdata_dt(spi); + spi->controller_data = cdata; + } +- + spin_lock_irqsave(&tqspi->lock, flags); + + /* keep default cs state to inactive */ +@@ -977,19 +1001,179 @@ static void tegra_qspi_transfer_end(struct spi_device *spi) + tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1); + } + +-static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi_message *msg) ++static u32 tegra_qspi_cmd_config(bool is_ddr, u8 bus_width, u8 len) ++{ ++ u32 cmd_config = 0; ++ ++ /* Extract Command configuration and value */ ++ if (is_ddr) ++ cmd_config |= QSPI_COMMAND_SDR_DDR; ++ else ++ cmd_config &= ~QSPI_COMMAND_SDR_DDR; ++ ++ cmd_config |= QSPI_COMMAND_X1_X2_X4(bus_width); ++ cmd_config |= QSPI_COMMAND_SIZE_SET((len * 8) - 1); ++ ++ return cmd_config; ++} ++ ++static u32 tegra_qspi_addr_config(bool is_ddr, u8 bus_width, u8 len) ++{ ++ u32 addr_config = 0; ++ ++ /* Extract Address configuration and value */ ++ is_ddr = 0; //Only SDR mode supported ++ bus_width = 0; //X1 mode ++ ++ if (is_ddr) ++ addr_config |= QSPI_ADDRESS_SDR_DDR; ++ else ++ addr_config &= ~QSPI_ADDRESS_SDR_DDR; ++ ++ addr_config |= QSPI_ADDRESS_X1_X2_X4(bus_width); ++ addr_config |= QSPI_ADDRESS_SIZE_SET((len * 8) - 1); ++ ++ return addr_config; ++} ++ ++static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, ++ struct spi_message *msg) ++{ ++ bool is_first_msg = true; ++ struct spi_transfer *xfer; ++ struct spi_device *spi = msg->spi; ++ u8 transfer_phase = 0; ++ u32 cmd1 = 0, dma_ctl = 0; ++ int ret = 0; ++ u32 address_value = 0; ++ u32 cmd_config = 0, addr_config = 0; ++ u8 cmd_value = 0, val = 0; ++ ++ /* Enable Combined sequence mode */ ++ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); ++ val |= QSPI_CMB_SEQ_EN; ++ tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); ++ /* Process individual transfer list */ ++ list_for_each_entry(xfer, &msg->transfers, transfer_list) { ++ switch (transfer_phase) { ++ case CMD_TRANSFER: ++ /* X1 SDR mode */ ++ cmd_config = tegra_qspi_cmd_config(false, 0, ++ xfer->len); ++ cmd_value = *((const u8 *)(xfer->tx_buf)); ++ break; ++ case ADDR_TRANSFER: ++ /* X1 SDR mode */ ++ addr_config = tegra_qspi_addr_config(false, 0, ++ xfer->len); ++ address_value = *((const u32 *)(xfer->tx_buf)); ++ break; ++ case DATA_TRANSFER: ++ /* Program Command, Address value in register */ ++ tegra_qspi_writel(tqspi, cmd_value, QSPI_CMB_SEQ_CMD); ++ tegra_qspi_writel(tqspi, address_value, ++ QSPI_CMB_SEQ_ADDR); ++ /* Program Command and Address config in register */ ++ tegra_qspi_writel(tqspi, cmd_config, ++ QSPI_CMB_SEQ_CMD_CFG); ++ tegra_qspi_writel(tqspi, addr_config, ++ QSPI_CMB_SEQ_ADDR_CFG); ++ ++ reinit_completion(&tqspi->xfer_completion); ++ cmd1 = tegra_qspi_setup_transfer_one(spi, xfer, ++ is_first_msg); ++ ret = tegra_qspi_start_transfer_one(spi, xfer, ++ cmd1); ++ ++ if (ret < 0) { ++ dev_err(tqspi->dev, "Failed to start transfer-one: %d\n", ++ ret); ++ return ret; ++ } ++ ++ is_first_msg = false; ++ ret = wait_for_completion_timeout ++ (&tqspi->xfer_completion, ++ QSPI_DMA_TIMEOUT); ++ ++ if (WARN_ON(ret == 0)) { ++ dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n", ++ ret); ++ if (tqspi->is_curr_dma_xfer && ++ (tqspi->cur_direction & DATA_DIR_TX)) ++ dmaengine_terminate_all ++ (tqspi->tx_dma_chan); ++ ++ if (tqspi->is_curr_dma_xfer && ++ (tqspi->cur_direction & DATA_DIR_RX)) ++ dmaengine_terminate_all ++ (tqspi->rx_dma_chan); ++ ++ /* Abort transfer by resetting pio/dma bit */ ++ if (!tqspi->is_curr_dma_xfer) { ++ cmd1 = tegra_qspi_readl ++ (tqspi, ++ QSPI_COMMAND1); ++ cmd1 &= ~QSPI_PIO; ++ tegra_qspi_writel ++ (tqspi, cmd1, ++ QSPI_COMMAND1); ++ } else { ++ dma_ctl = tegra_qspi_readl ++ (tqspi, ++ QSPI_DMA_CTL); ++ dma_ctl &= ~QSPI_DMA_EN; ++ tegra_qspi_writel(tqspi, dma_ctl, ++ QSPI_DMA_CTL); ++ } ++ ++ /* Reset controller if timeout happens */ ++ if (device_reset(tqspi->dev) < 0) ++ dev_warn_once(tqspi->dev, ++ "device reset failed\n"); ++ ret = -EIO; ++ goto exit; ++ } ++ ++ if (tqspi->tx_status || tqspi->rx_status) { ++ dev_err(tqspi->dev, "QSPI Transfer failed\n"); ++ tqspi->tx_status = 0; ++ tqspi->rx_status = 0; ++ ret = -EIO; ++ goto exit; ++ } ++ break; ++ default: ++ ret = -EINVAL; ++ goto exit; ++ } ++ msg->actual_length += xfer->len; ++ transfer_phase++; ++ } ++ ++exit: ++ msg->status = ret; ++ ++ return ret; ++} ++ ++static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, ++ struct spi_message *msg) + { +- struct tegra_qspi *tqspi = spi_master_get_devdata(master); + struct spi_device *spi = msg->spi; + struct spi_transfer *transfer; + bool is_first_msg = true; +- int ret; ++ int ret = 0, val = 0; + + msg->status = 0; + msg->actual_length = 0; + tqspi->tx_status = 0; + tqspi->rx_status = 0; + ++ /* Disable Combined sequence mode */ ++ val = tegra_qspi_readl(tqspi, QSPI_GLOBAL_CONFIG); ++ val &= ~QSPI_CMB_SEQ_EN; ++ tegra_qspi_writel(tqspi, val, QSPI_GLOBAL_CONFIG); + list_for_each_entry(transfer, &msg->transfers, transfer_list) { + struct spi_transfer *xfer = transfer; + u8 dummy_bytes = 0; +@@ -1027,7 +1211,6 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi + goto complete_xfer; + } + +- is_first_msg = false; + ret = wait_for_completion_timeout(&tqspi->xfer_completion, + QSPI_DMA_TIMEOUT); + if (WARN_ON(ret == 0)) { +@@ -1072,7 +1255,48 @@ static int tegra_qspi_transfer_one_message(struct spi_master *master, struct spi + ret = 0; + exit: + msg->status = ret; ++ ++ return ret; ++} ++ ++static bool tegra_qspi_validate_cmb_seq(struct tegra_qspi *tqspi, ++ struct spi_message *msg) ++{ ++ int transfer_count = 0; ++ struct spi_transfer *xfer; ++ ++ list_for_each_entry(xfer, &msg->transfers, transfer_list) { ++ transfer_count++; ++ } ++ if (!tqspi->soc_data->cmb_xfer_capable || transfer_count != 3) ++ return false; ++ xfer = list_first_entry(&msg->transfers, typeof(*xfer), ++ transfer_list); ++ if (xfer->len > 2) ++ return false; ++ xfer = list_next_entry(xfer, transfer_list); ++ if (xfer->len > 4 || xfer->len < 3) ++ return false; ++ xfer = list_next_entry(xfer, transfer_list); ++ if (!tqspi->soc_data->has_dma || xfer->len > (QSPI_FIFO_DEPTH << 2)) ++ return false; ++ ++ return true; ++} ++ ++static int tegra_qspi_transfer_one_message(struct spi_master *master, ++ struct spi_message *msg) ++{ ++ struct tegra_qspi *tqspi = spi_master_get_devdata(master); ++ int ret; ++ ++ if (tegra_qspi_validate_cmb_seq(tqspi, msg)) ++ ret = tegra_qspi_combined_seq_xfer(tqspi, msg); ++ else ++ ret = tegra_qspi_non_combined_seq_xfer(tqspi, msg); ++ + spi_finalize_current_message(master); ++ + return ret; + } + +@@ -1206,14 +1430,17 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + + static struct tegra_qspi_soc_data tegra210_qspi_soc_data = { + .has_dma = true, ++ .cmb_xfer_capable = false, + }; + + static struct tegra_qspi_soc_data tegra186_qspi_soc_data = { + .has_dma = true, ++ .cmb_xfer_capable = true, + }; + + static struct tegra_qspi_soc_data tegra234_qspi_soc_data = { + .has_dma = false, ++ .cmb_xfer_capable = true, + }; + + static const struct of_device_id tegra_qspi_of_match[] = { +@@ -1267,6 +1494,7 @@ static int tegra_qspi_probe(struct platform_device *pdev) + tqspi->dev = &pdev->dev; + spin_lock_init(&tqspi->lock); + ++ tqspi->soc_data = device_get_match_data(&pdev->dev); + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + tqspi->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(tqspi->base)) +-- +2.51.0 + diff --git a/queue-5.15/spi-tegra210-quad-fix-timeout-handling.patch b/queue-5.15/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..cc79846432 --- /dev/null +++ b/queue-5.15/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,116 @@ +From fcff32bbb1fb823cd7208ee4c0426808fa39cf08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 50243a520158c..9111430469786 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -984,8 +984,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1128,9 +1130,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1152,10 +1156,12 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1237,6 +1243,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1333,6 +1341,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1416,6 +1425,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-5.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch b/queue-5.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch new file mode 100644 index 0000000000..a7ed3d9b71 --- /dev/null +++ b/queue-5.15/spi-tegra210-quad-modify-chip-select-cs-deactivation.patch @@ -0,0 +1,42 @@ +From 8616e054b4ba9a5accf01cdd61f0decb8a823549 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 16 Apr 2025 11:06:03 +0000 +Subject: spi: tegra210-quad: modify chip select (CS) deactivation + +From: Vishwaroop A + +[ Upstream commit d8966b65413390d1b5b706886987caac05fbe024 ] + +Modify the chip select (CS) deactivation and inter-transfer delay +execution only during the DATA_TRANSFER phase when the cs_change +flag is not set. This ensures proper CS handling and timing between +transfers while eliminating redundant operations. + +Fixes: 1b8342cc4a38 ("spi: tegra210-quad: combined sequence mode") +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20250416110606.2737315-4-va@nvidia.com +Signed-off-by: Mark Brown +Stable-dep-of: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index ff6a2c297b8af..50243a520158c 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -1148,6 +1148,10 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + goto exit; + } + msg->actual_length += xfer->len; ++ if (!xfer->cs_change && transfer_phase == DATA_TRANSFER) { ++ tegra_qspi_transfer_end(spi); ++ spi_transfer_delay_exec(xfer); ++ } + transfer_phase++; + } + +-- +2.51.0 + diff --git a/queue-5.15/spi-tegra210-quad-use-device_reset-method.patch b/queue-5.15/spi-tegra210-quad-use-device_reset-method.patch new file mode 100644 index 0000000000..ebb467e1fd --- /dev/null +++ b/queue-5.15/spi-tegra210-quad-use-device_reset-method.patch @@ -0,0 +1,74 @@ +From b92c4236062be46ac9fc34df906d74c749fbef23 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 22 Feb 2022 23:26:07 +0530 +Subject: spi: tegra210-quad: use device_reset method + +From: Krishna Yarlagadda + +[ Upstream commit ac982578e7d340dc4f4fd243f4a4b24787d28c3f ] + +Use device_reset api to replace duplicate code in driver to call +reset_control_get api with reset handle. + +Signed-off-by: Krishna Yarlagadda +Link: https://lore.kernel.org/r/20220222175611.58051-2-kyarlagadda@nvidia.com +Signed-off-by: Mark Brown +Stable-dep-of: b4e002d8a7ce ("spi: tegra210-quad: Fix timeout handling") +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 18 ++++-------------- + 1 file changed, 4 insertions(+), 14 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 3432058b0a7bd..c3867c70c61d4 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -137,7 +137,6 @@ struct tegra_qspi { + spinlock_t lock; + + struct clk *clk; +- struct reset_control *rst; + void __iomem *base; + phys_addr_t phys; + unsigned int irq; +@@ -956,9 +955,8 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- reset_control_assert(tqspi->rst); +- udelay(2); +- reset_control_deassert(tqspi->rst); ++ if (device_reset(tqspi->dev) < 0) ++ dev_warn_once(tqspi->dev, "device reset failed\n"); + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1260,13 +1258,6 @@ static int tegra_qspi_probe(struct platform_device *pdev) + return ret; + } + +- tqspi->rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); +- if (IS_ERR(tqspi->rst)) { +- ret = PTR_ERR(tqspi->rst); +- dev_err(&pdev->dev, "failed to get reset control: %d\n", ret); +- return ret; +- } +- + tqspi->max_buf_size = QSPI_FIFO_DEPTH << 2; + tqspi->dma_buf_size = DEFAULT_QSPI_DMA_BUF_LEN; + +@@ -1288,9 +1279,8 @@ static int tegra_qspi_probe(struct platform_device *pdev) + goto exit_pm_disable; + } + +- reset_control_assert(tqspi->rst); +- udelay(2); +- reset_control_deassert(tqspi->rst); ++ if (device_reset(tqspi->dev) < 0) ++ dev_warn_once(tqspi->dev, "device reset failed\n"); + + tqspi->def_command1_reg = QSPI_M_S | QSPI_CS_SW_HW | QSPI_CS_SW_VAL; + tegra_qspi_writel(tqspi, tqspi->def_command1_reg, QSPI_COMMAND1); +-- +2.51.0 + diff --git a/queue-5.15/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-5.15/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..f6bb73831c --- /dev/null +++ b/queue-5.15/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From 4726f5fea14ec4005d9224dd26cbb7e357741c91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 54620ae6919bc..67604a4d9a39f 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1228,8 +1228,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-5.15/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-5.15/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..6a2c4b2a80 --- /dev/null +++ b/queue-5.15/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From acde0c5a7b7d18ca91a5515b6f46aec79ee1b37c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 7d8eb9dc20681..db4e64550f121 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-5.15/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-5.15/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..8e01ee85f9 --- /dev/null +++ b/queue-5.15/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From 45abd2b03cf94b6d9bbff5fd1f763de8723cd841 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index d99d424c05a7a..50909cc9a0bb2 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -445,9 +445,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-5.15/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch b/queue-5.15/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch new file mode 100644 index 0000000000..44bad49b14 --- /dev/null +++ b/queue-5.15/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch @@ -0,0 +1,45 @@ +From 857f07b5a4a1f003626228f4df1c9adba55b1682 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Jun 2025 17:46:55 +0800 +Subject: usb: dwc2: disable platform lowlevel hw resources during shutdown + +From: Jisheng Zhang + +[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ] + +On some SoC platforms, in shutdown stage, most components' power is cut +off, but there's still power supply to the so called always-on +domain, so if the dwc2's regulator is from the always-on domain, we +need to explicitly disable it to save power. + +Disable platform lowlevel hw resources such as phy, clock and +regulators etc. in device shutdown hook to reduce non-necessary power +consumption when the platform enters shutdown stage. + +Signed-off-by: Jisheng Zhang +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 5ff8186936790..8bdbae4c77b0a 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -386,6 +386,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); ++ ++ if (hsotg->ll_hw_enabled) ++ dwc2_lowlevel_hw_disable(hsotg); + } + + /** +-- +2.51.0 + diff --git a/queue-5.15/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-5.15/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..31baad1ce0 --- /dev/null +++ b/queue-5.15/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From d983e63a8c0590dcfe57b1e15c1d0a46e2947302 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 8bdbae4c77b0a..ae2d73c5aa811 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -384,11 +384,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-5.15/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-5.15/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..c4bbd40c21 --- /dev/null +++ b/queue-5.15/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From a4787d9c556e5f5e9568f239d44e4e6b5cd29ba2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index ae2d73c5aa811..c9fa8c3ff425a 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -669,9 +669,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -722,6 +726,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-5.15/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-5.15/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..5de50bf9a2 --- /dev/null +++ b/queue-5.15/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From 46cfffc332c91057ba0daadd3161afb83d0237a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index 1673e5d089263..9f65556dc3745 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2386,7 +2386,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-5.15/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-5.15/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..d969a0e3b1 --- /dev/null +++ b/queue-5.15/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 129c389aee3e8ea3cc2aebe17b87191df071453f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index 17e39f3e908b2..db700db32eef2 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -39,6 +39,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -620,6 +621,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-5.15/vdpa-introduce-and-use-vdpa-device-get-set-config-he.patch b/queue-5.15/vdpa-introduce-and-use-vdpa-device-get-set-config-he.patch new file mode 100644 index 0000000000..eb3f2e5b23 --- /dev/null +++ b/queue-5.15/vdpa-introduce-and-use-vdpa-device-get-set-config-he.patch @@ -0,0 +1,150 @@ +From 654161ce022caa0e1da0395ab5647b32e503dc66 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Oct 2021 20:55:12 +0300 +Subject: vdpa: Introduce and use vdpa device get, set config helpers + +From: Parav Pandit + +[ Upstream commit 6dbb1f1687a2ccdfc5b84b0a35bbc6dfefc4de3b ] + +Subsequent patches enable get and set configuration either +via management device or via vdpa device' config ops. + +This requires synchronization between multiple callers to get and set +config callbacks. Features setting also influence the layout of the +configuration fields endianness. + +To avoid exposing synchronization primitives to callers, introduce +helper for setting the configuration and use it. + +Signed-off-by: Parav Pandit +Reviewed-by: Eli Cohen +Acked-by: Jason Wang +Reviewed-by: Stefano Garzarella +Link: https://lore.kernel.org/r/20211026175519.87795-2-parav@nvidia.com +Signed-off-by: Michael S. Tsirkin +Stable-dep-of: e40b6abe0b12 ("virtio_vdpa: fix misleading return in void function") +Signed-off-by: Sasha Levin +--- + drivers/vdpa/vdpa.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/vhost/vdpa.c | 3 +-- + drivers/virtio/virtio_vdpa.c | 3 +-- + include/linux/vdpa.h | 19 ++++--------------- + 4 files changed, 42 insertions(+), 19 deletions(-) + +diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c +index 86571498c1c23..563b06563e17a 100644 +--- a/drivers/vdpa/vdpa.c ++++ b/drivers/vdpa/vdpa.c +@@ -289,6 +289,42 @@ void vdpa_mgmtdev_unregister(struct vdpa_mgmt_dev *mdev) + } + EXPORT_SYMBOL_GPL(vdpa_mgmtdev_unregister); + ++/** ++ * vdpa_get_config - Get one or more device configuration fields. ++ * @vdev: vdpa device to operate on ++ * @offset: starting byte offset of the field ++ * @buf: buffer pointer to read to ++ * @len: length of the configuration fields in bytes ++ */ ++void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, ++ void *buf, unsigned int len) ++{ ++ const struct vdpa_config_ops *ops = vdev->config; ++ ++ /* ++ * Config accesses aren't supposed to trigger before features are set. ++ * If it does happen we assume a legacy guest. ++ */ ++ if (!vdev->features_valid) ++ vdpa_set_features(vdev, 0); ++ ops->get_config(vdev, offset, buf, len); ++} ++EXPORT_SYMBOL_GPL(vdpa_get_config); ++ ++/** ++ * vdpa_set_config - Set one or more device configuration fields. ++ * @vdev: vdpa device to operate on ++ * @offset: starting byte offset of the field ++ * @buf: buffer pointer to read from ++ * @length: length of the configuration fields in bytes ++ */ ++void vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, ++ const void *buf, unsigned int length) ++{ ++ vdev->config->set_config(vdev, offset, buf, length); ++} ++EXPORT_SYMBOL_GPL(vdpa_set_config); ++ + static bool mgmtdev_handle_match(const struct vdpa_mgmt_dev *mdev, + const char *busname, const char *devname) + { +diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c +index 58ba684037f9e..0f61ca0598b71 100644 +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -238,7 +238,6 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v, + struct vhost_vdpa_config __user *c) + { + struct vdpa_device *vdpa = v->vdpa; +- const struct vdpa_config_ops *ops = vdpa->config; + struct vhost_vdpa_config config; + unsigned long size = offsetof(struct vhost_vdpa_config, buf); + u8 *buf; +@@ -252,7 +251,7 @@ static long vhost_vdpa_set_config(struct vhost_vdpa *v, + if (IS_ERR(buf)) + return PTR_ERR(buf); + +- ops->set_config(vdpa, config.off, buf, config.len); ++ vdpa_set_config(vdpa, config.off, buf, config.len); + + kvfree(buf); + return 0; +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index 1c29446aafb44..b5ab5f59f96ac 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -65,9 +65,8 @@ static void virtio_vdpa_set(struct virtio_device *vdev, unsigned offset, + const void *buf, unsigned len) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); +- const struct vdpa_config_ops *ops = vdpa->config; + +- ops->set_config(vdpa, offset, buf, len); ++ vdpa_set_config(vdpa, offset, buf, len); + } + + static u32 virtio_vdpa_generation(struct virtio_device *vdev) +diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h +index 4fb198c8dbf61..88ed82e03b666 100644 +--- a/include/linux/vdpa.h ++++ b/include/linux/vdpa.h +@@ -388,21 +388,10 @@ static inline int vdpa_set_features(struct vdpa_device *vdev, u64 features) + return ops->set_features(vdev, features); + } + +-static inline void vdpa_get_config(struct vdpa_device *vdev, +- unsigned int offset, void *buf, +- unsigned int len) +-{ +- const struct vdpa_config_ops *ops = vdev->config; +- +- /* +- * Config accesses aren't supposed to trigger before features are set. +- * If it does happen we assume a legacy guest. +- */ +- if (!vdev->features_valid) +- vdpa_set_features(vdev, 0); +- ops->get_config(vdev, offset, buf, len); +-} +- ++void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, ++ void *buf, unsigned int len); ++void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, ++ const void *buf, unsigned int length); + /** + * struct vdpa_mgmtdev_ops - vdpa device ops + * @dev_add: Add a vdpa device using alloc and register +-- +2.51.0 + diff --git a/queue-5.15/vdpa-introduce-query-of-device-config-layout.patch b/queue-5.15/vdpa-introduce-query-of-device-config-layout.patch new file mode 100644 index 0000000000..de1c9021d4 --- /dev/null +++ b/queue-5.15/vdpa-introduce-query-of-device-config-layout.patch @@ -0,0 +1,327 @@ +From de112b5affcd044f81e3e456c81f6162fddf0d8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Oct 2021 20:55:13 +0300 +Subject: vdpa: Introduce query of device config layout + +From: Parav Pandit + +[ Upstream commit ad69dd0bf26b88ec6ab26f8bbe5cd74fbed7672a ] + +Introduce a command to query a device config layout. + +An example query of network vdpa device: + +$ vdpa dev add name bar mgmtdev vdpasim_net + +$ vdpa dev config show +bar: mac 00:35:09:19:48:05 link up link_announce false mtu 1500 + +$ vdpa dev config show -jp +{ + "config": { + "bar": { + "mac": "00:35:09:19:48:05", + "link ": "up", + "link_announce ": false, + "mtu": 1500, + } + } +} + +Signed-off-by: Parav Pandit +Signed-off-by: Eli Cohen +Acked-by: Jason Wang +Link: https://lore.kernel.org/r/20211026175519.87795-3-parav@nvidia.com +Signed-off-by: Michael S. Tsirkin +Stable-dep-of: e40b6abe0b12 ("virtio_vdpa: fix misleading return in void function") +Signed-off-by: Sasha Levin +--- + drivers/vdpa/vdpa.c | 176 ++++++++++++++++++++++++++++++++++++++ + include/linux/vdpa.h | 2 + + include/uapi/linux/vdpa.h | 6 ++ + 3 files changed, 184 insertions(+) + +diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c +index 563b06563e17a..b12fc70510bb7 100644 +--- a/drivers/vdpa/vdpa.c ++++ b/drivers/vdpa/vdpa.c +@@ -14,6 +14,8 @@ + #include + #include + #include ++#include ++#include + + static LIST_HEAD(mdev_head); + /* A global mutex that protects vdpa management device and device level operations. */ +@@ -58,6 +60,7 @@ static void vdpa_release_dev(struct device *d) + ops->free(vdev); + + ida_simple_remove(&vdpa_index_ida, vdev->index); ++ mutex_destroy(&vdev->cf_mutex); + kfree(vdev); + } + +@@ -119,6 +122,7 @@ struct vdpa_device *__vdpa_alloc_device(struct device *parent, + if (err) + goto err_name; + ++ mutex_init(&vdev->cf_mutex); + device_initialize(&vdev->dev); + + return vdev; +@@ -301,6 +305,7 @@ void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, + { + const struct vdpa_config_ops *ops = vdev->config; + ++ mutex_lock(&vdev->cf_mutex); + /* + * Config accesses aren't supposed to trigger before features are set. + * If it does happen we assume a legacy guest. +@@ -308,6 +313,7 @@ void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, + if (!vdev->features_valid) + vdpa_set_features(vdev, 0); + ops->get_config(vdev, offset, buf, len); ++ mutex_unlock(&vdev->cf_mutex); + } + EXPORT_SYMBOL_GPL(vdpa_get_config); + +@@ -321,7 +327,9 @@ EXPORT_SYMBOL_GPL(vdpa_get_config); + void vdpa_set_config(struct vdpa_device *vdev, unsigned int offset, + const void *buf, unsigned int length) + { ++ mutex_lock(&vdev->cf_mutex); + vdev->config->set_config(vdev, offset, buf, length); ++ mutex_unlock(&vdev->cf_mutex); + } + EXPORT_SYMBOL_GPL(vdpa_set_config); + +@@ -654,6 +662,168 @@ static int vdpa_nl_cmd_dev_get_dumpit(struct sk_buff *msg, struct netlink_callba + return msg->len; + } + ++static int vdpa_dev_net_mq_config_fill(struct vdpa_device *vdev, ++ struct sk_buff *msg, u64 features, ++ const struct virtio_net_config *config) ++{ ++ u16 val_u16; ++ ++ if ((features & (1ULL << VIRTIO_NET_F_MQ)) == 0) ++ return 0; ++ ++ val_u16 = le16_to_cpu(config->max_virtqueue_pairs); ++ return nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MAX_VQP, val_u16); ++} ++ ++static int vdpa_dev_net_config_fill(struct vdpa_device *vdev, struct sk_buff *msg) ++{ ++ struct virtio_net_config config = {}; ++ u64 features; ++ u16 val_u16; ++ ++ vdpa_get_config(vdev, 0, &config, sizeof(config)); ++ ++ if (nla_put(msg, VDPA_ATTR_DEV_NET_CFG_MACADDR, sizeof(config.mac), ++ config.mac)) ++ return -EMSGSIZE; ++ ++ val_u16 = le16_to_cpu(config.status); ++ if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_STATUS, val_u16)) ++ return -EMSGSIZE; ++ ++ val_u16 = le16_to_cpu(config.mtu); ++ if (nla_put_u16(msg, VDPA_ATTR_DEV_NET_CFG_MTU, val_u16)) ++ return -EMSGSIZE; ++ ++ features = vdev->config->get_features(vdev); ++ ++ return vdpa_dev_net_mq_config_fill(vdev, msg, features, &config); ++} ++ ++static int ++vdpa_dev_config_fill(struct vdpa_device *vdev, struct sk_buff *msg, u32 portid, u32 seq, ++ int flags, struct netlink_ext_ack *extack) ++{ ++ u32 device_id; ++ void *hdr; ++ int err; ++ ++ hdr = genlmsg_put(msg, portid, seq, &vdpa_nl_family, flags, ++ VDPA_CMD_DEV_CONFIG_GET); ++ if (!hdr) ++ return -EMSGSIZE; ++ ++ if (nla_put_string(msg, VDPA_ATTR_DEV_NAME, dev_name(&vdev->dev))) { ++ err = -EMSGSIZE; ++ goto msg_err; ++ } ++ ++ device_id = vdev->config->get_device_id(vdev); ++ if (nla_put_u32(msg, VDPA_ATTR_DEV_ID, device_id)) { ++ err = -EMSGSIZE; ++ goto msg_err; ++ } ++ ++ switch (device_id) { ++ case VIRTIO_ID_NET: ++ err = vdpa_dev_net_config_fill(vdev, msg); ++ break; ++ default: ++ err = -EOPNOTSUPP; ++ break; ++ } ++ if (err) ++ goto msg_err; ++ ++ genlmsg_end(msg, hdr); ++ return 0; ++ ++msg_err: ++ genlmsg_cancel(msg, hdr); ++ return err; ++} ++ ++static int vdpa_nl_cmd_dev_config_get_doit(struct sk_buff *skb, struct genl_info *info) ++{ ++ struct vdpa_device *vdev; ++ struct sk_buff *msg; ++ const char *devname; ++ struct device *dev; ++ int err; ++ ++ if (!info->attrs[VDPA_ATTR_DEV_NAME]) ++ return -EINVAL; ++ devname = nla_data(info->attrs[VDPA_ATTR_DEV_NAME]); ++ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); ++ if (!msg) ++ return -ENOMEM; ++ ++ mutex_lock(&vdpa_dev_mutex); ++ dev = bus_find_device(&vdpa_bus, NULL, devname, vdpa_name_match); ++ if (!dev) { ++ NL_SET_ERR_MSG_MOD(info->extack, "device not found"); ++ err = -ENODEV; ++ goto dev_err; ++ } ++ vdev = container_of(dev, struct vdpa_device, dev); ++ if (!vdev->mdev) { ++ NL_SET_ERR_MSG_MOD(info->extack, "unmanaged vdpa device"); ++ err = -EINVAL; ++ goto mdev_err; ++ } ++ err = vdpa_dev_config_fill(vdev, msg, info->snd_portid, info->snd_seq, ++ 0, info->extack); ++ if (!err) ++ err = genlmsg_reply(msg, info); ++ ++mdev_err: ++ put_device(dev); ++dev_err: ++ mutex_unlock(&vdpa_dev_mutex); ++ if (err) ++ nlmsg_free(msg); ++ return err; ++} ++ ++static int vdpa_dev_config_dump(struct device *dev, void *data) ++{ ++ struct vdpa_device *vdev = container_of(dev, struct vdpa_device, dev); ++ struct vdpa_dev_dump_info *info = data; ++ int err; ++ ++ if (!vdev->mdev) ++ return 0; ++ if (info->idx < info->start_idx) { ++ info->idx++; ++ return 0; ++ } ++ err = vdpa_dev_config_fill(vdev, info->msg, NETLINK_CB(info->cb->skb).portid, ++ info->cb->nlh->nlmsg_seq, NLM_F_MULTI, ++ info->cb->extack); ++ if (err) ++ return err; ++ ++ info->idx++; ++ return 0; ++} ++ ++static int ++vdpa_nl_cmd_dev_config_get_dumpit(struct sk_buff *msg, struct netlink_callback *cb) ++{ ++ struct vdpa_dev_dump_info info; ++ ++ info.msg = msg; ++ info.cb = cb; ++ info.start_idx = cb->args[0]; ++ info.idx = 0; ++ ++ mutex_lock(&vdpa_dev_mutex); ++ bus_for_each_dev(&vdpa_bus, NULL, &info, vdpa_dev_config_dump); ++ mutex_unlock(&vdpa_dev_mutex); ++ cb->args[0] = info.idx; ++ return msg->len; ++} ++ + static const struct nla_policy vdpa_nl_policy[VDPA_ATTR_MAX + 1] = { + [VDPA_ATTR_MGMTDEV_BUS_NAME] = { .type = NLA_NUL_STRING }, + [VDPA_ATTR_MGMTDEV_DEV_NAME] = { .type = NLA_STRING }, +@@ -685,6 +855,12 @@ static const struct genl_ops vdpa_nl_ops[] = { + .doit = vdpa_nl_cmd_dev_get_doit, + .dumpit = vdpa_nl_cmd_dev_get_dumpit, + }, ++ { ++ .cmd = VDPA_CMD_DEV_CONFIG_GET, ++ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, ++ .doit = vdpa_nl_cmd_dev_config_get_doit, ++ .dumpit = vdpa_nl_cmd_dev_config_get_dumpit, ++ }, + }; + + static struct genl_family vdpa_nl_family __ro_after_init = { +diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h +index 88ed82e03b666..d26f5777f30f7 100644 +--- a/include/linux/vdpa.h ++++ b/include/linux/vdpa.h +@@ -69,6 +69,7 @@ struct vdpa_mgmt_dev; + * @dev: underlying device + * @dma_dev: the actual device that is performing DMA + * @config: the configuration ops for this device. ++ * @cf_mutex: Protects get and set access to configuration layout. + * @index: device index + * @features_valid: were features initialized? for legacy guests + * @use_va: indicate whether virtual address must be used by this device +@@ -80,6 +81,7 @@ struct vdpa_device { + struct device dev; + struct device *dma_dev; + const struct vdpa_config_ops *config; ++ struct mutex cf_mutex; /* Protects get/set config */ + unsigned int index; + bool features_valid; + bool use_va; +diff --git a/include/uapi/linux/vdpa.h b/include/uapi/linux/vdpa.h +index 66a41e4ec163a..37ef30130a283 100644 +--- a/include/uapi/linux/vdpa.h ++++ b/include/uapi/linux/vdpa.h +@@ -17,6 +17,7 @@ enum vdpa_command { + VDPA_CMD_DEV_NEW, + VDPA_CMD_DEV_DEL, + VDPA_CMD_DEV_GET, /* can dump */ ++ VDPA_CMD_DEV_CONFIG_GET, /* can dump */ + }; + + enum vdpa_attr { +@@ -33,6 +34,11 @@ enum vdpa_attr { + VDPA_ATTR_DEV_MAX_VQS, /* u32 */ + VDPA_ATTR_DEV_MAX_VQ_SIZE, /* u16 */ + ++ VDPA_ATTR_DEV_NET_CFG_MACADDR, /* binary */ ++ VDPA_ATTR_DEV_NET_STATUS, /* u8 */ ++ VDPA_ATTR_DEV_NET_CFG_MAX_VQP, /* u16 */ ++ VDPA_ATTR_DEV_NET_CFG_MTU, /* u16 */ ++ + /* new attributes must be added above here */ + VDPA_ATTR_MAX, + }; +-- +2.51.0 + diff --git a/queue-5.15/vdpa-sync-calls-set-get-config-status-with-cf_mutex.patch b/queue-5.15/vdpa-sync-calls-set-get-config-status-with-cf_mutex.patch new file mode 100644 index 0000000000..36ebaef04e --- /dev/null +++ b/queue-5.15/vdpa-sync-calls-set-get-config-status-with-cf_mutex.patch @@ -0,0 +1,121 @@ +From d9953b35fcc8bf701849934770d443996ffd94b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Jan 2022 13:46:35 +0200 +Subject: vdpa: Sync calls set/get config/status with cf_mutex + +From: Eli Cohen + +[ Upstream commit 73bc0dbb591baea322a7319c735e5f6c7dba9cfb ] + +Add wrappers to get/set status and protect these operations with +cf_mutex to serialize these operations with respect to get/set config +operations. + +Signed-off-by: Eli Cohen +Link: https://lore.kernel.org/r/20220105114646.577224-4-elic@nvidia.com +Signed-off-by: Michael S. Tsirkin +Stable-dep-of: e40b6abe0b12 ("virtio_vdpa: fix misleading return in void function") +Signed-off-by: Sasha Levin +--- + drivers/vdpa/vdpa.c | 19 +++++++++++++++++++ + drivers/vhost/vdpa.c | 7 +++---- + drivers/virtio/virtio_vdpa.c | 3 +-- + include/linux/vdpa.h | 3 +++ + 4 files changed, 26 insertions(+), 6 deletions(-) + +diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c +index b12fc70510bb7..58eb448bf5b0c 100644 +--- a/drivers/vdpa/vdpa.c ++++ b/drivers/vdpa/vdpa.c +@@ -22,6 +22,25 @@ static LIST_HEAD(mdev_head); + static DEFINE_MUTEX(vdpa_dev_mutex); + static DEFINE_IDA(vdpa_index_ida); + ++u8 vdpa_get_status(struct vdpa_device *vdev) ++{ ++ u8 status; ++ ++ mutex_lock(&vdev->cf_mutex); ++ status = vdev->config->get_status(vdev); ++ mutex_unlock(&vdev->cf_mutex); ++ return status; ++} ++EXPORT_SYMBOL(vdpa_get_status); ++ ++void vdpa_set_status(struct vdpa_device *vdev, u8 status) ++{ ++ mutex_lock(&vdev->cf_mutex); ++ vdev->config->set_status(vdev, status); ++ mutex_unlock(&vdev->cf_mutex); ++} ++EXPORT_SYMBOL(vdpa_set_status); ++ + static struct genl_family vdpa_nl_family; + + static int vdpa_dev_probe(struct device *d) +diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c +index 0f61ca0598b71..802c84e296e21 100644 +--- a/drivers/vhost/vdpa.c ++++ b/drivers/vhost/vdpa.c +@@ -143,10 +143,9 @@ static long vhost_vdpa_get_device_id(struct vhost_vdpa *v, u8 __user *argp) + static long vhost_vdpa_get_status(struct vhost_vdpa *v, u8 __user *statusp) + { + struct vdpa_device *vdpa = v->vdpa; +- const struct vdpa_config_ops *ops = vdpa->config; + u8 status; + +- status = ops->get_status(vdpa); ++ status = vdpa_get_status(vdpa); + + if (copy_to_user(statusp, &status, sizeof(status))) + return -EFAULT; +@@ -165,7 +164,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) + if (copy_from_user(&status, statusp, sizeof(status))) + return -EFAULT; + +- status_old = ops->get_status(vdpa); ++ status_old = vdpa_get_status(vdpa); + + /* + * Userspace shouldn't remove status bits unless reset the +@@ -183,7 +182,7 @@ static long vhost_vdpa_set_status(struct vhost_vdpa *v, u8 __user *statusp) + if (ret) + return ret; + } else +- ops->set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + + if ((status & VIRTIO_CONFIG_S_DRIVER_OK) && !(status_old & VIRTIO_CONFIG_S_DRIVER_OK)) + for (i = 0; i < nvqs; i++) +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index b5ab5f59f96ac..a85a10d65973f 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -91,9 +91,8 @@ static u8 virtio_vdpa_get_status(struct virtio_device *vdev) + static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); +- const struct vdpa_config_ops *ops = vdpa->config; + +- return ops->set_status(vdpa, status); ++ return vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h +index d26f5777f30f7..c0c8ed2c62fd8 100644 +--- a/include/linux/vdpa.h ++++ b/include/linux/vdpa.h +@@ -394,6 +394,9 @@ void vdpa_get_config(struct vdpa_device *vdev, unsigned int offset, + void *buf, unsigned int len); + void vdpa_set_config(struct vdpa_device *dev, unsigned int offset, + const void *buf, unsigned int length); ++u8 vdpa_get_status(struct vdpa_device *vdev); ++void vdpa_set_status(struct vdpa_device *vdev, u8 status); ++ + /** + * struct vdpa_mgmtdev_ops - vdpa device ops + * @dev_add: Add a vdpa device using alloc and register +-- +2.51.0 + diff --git a/queue-5.15/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-5.15/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..38a6776ff6 --- /dev/null +++ b/queue-5.15/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From 254cb190061e6e8e5045c240e14468bdc57b2ed9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index b341dd62aa4da..f971986fa0e9a 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -247,7 +247,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu: the cpu no. + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-5.15/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-5.15/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..286af6a804 --- /dev/null +++ b/queue-5.15/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From c10413f7b918fc179a0fe1a4ddf3d0f504f2e359 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index a85a10d65973f..af085b3df4562 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -92,7 +92,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-5.15/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-5.15/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..38631c42dd --- /dev/null +++ b/queue-5.15/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From bffa51d5799091e5c35c2abaffd280c962576264 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 51cd99428940a..88e87cab5966a 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -327,19 +327,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_hw_heartbeat_ms = wdat->period * tbl->min_count; +@@ -356,15 +364,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -386,8 +399,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -418,7 +433,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -426,8 +442,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -441,7 +459,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -459,12 +477,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + #ifdef CONFIG_PM_SLEEP +-- +2.51.0 + diff --git a/queue-5.15/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch b/queue-5.15/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch new file mode 100644 index 0000000000..97a3b6973b --- /dev/null +++ b/queue-5.15/watchdog-wdat_wdt-stop-watchdog-when-uninstalling-mo.patch @@ -0,0 +1,39 @@ +From 8954d04cee6e4f7fd001d6d9adeedf930bebbeb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Apr 2022 22:53:30 +0800 +Subject: watchdog: wdat_wdt: Stop watchdog when uninstalling module + +From: Liu Xinpeng + +[ Upstream commit 330415ebea81b65842e4cc6d2fd985c1b369e650 ] + +Test shows that wachdog still reboots machine after the module +is removed. Use watchdog_stop_on_unregister to stop the watchdog +on removing. + +Signed-off-by: Liu Xinpeng +eviewed-by: Guenter Roeck +Link: https://lore.kernel.org/r/1650984810-6247-4-git-send-email-liuxp11@chinatelecom.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Stable-dep-of: 25c0b472eab8 ("watchdog: wdat_wdt: Fix ACPI table leak in probe function") +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 4fac8148a8e62..51cd99428940a 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -463,6 +463,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); ++ watchdog_stop_on_unregister(&wdat->wdd); + return devm_watchdog_register_device(dev, &wdat->wdd); + } + +-- +2.51.0 + diff --git a/queue-5.15/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-5.15/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..687f9bfa38 --- /dev/null +++ b/queue-5.15/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From 802fa3dbc9fcbe4411db0a8b0c3316e1ca030df9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 10e019cddcc65..cbb95682d21b2 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-5.15/wifi-ieee80211-correct-fils-status-codes.patch b/queue-5.15/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..0538423ef5 --- /dev/null +++ b/queue-5.15/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From f4bffc5c9645bf0f8d0dd02897ff3c912a3dac3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 00ed7c17698d1..0c00a628cbde7 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -2720,8 +2720,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + }; +-- +2.51.0 + diff --git a/queue-5.15/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-5.15/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..fb83459581 --- /dev/null +++ b/queue-5.15/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 806d0b0c7a050c025cfc6204af64248001760728 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index 025619cd14e82..acd6743f3827f 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-5.15/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-5.15/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..2e120283ef --- /dev/null +++ b/queue-5.15/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From 93fa949641960cab83ea78851b31a757664eebef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index c9df185dc3f4f..00493a2391179 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-5.15/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-5.15/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..25d41c568c --- /dev/null +++ b/queue-5.15/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From 69cc69f25eaf3785a858cf10eca2152f82c3a3cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 4adbc85b74a33..82ade5a7879ff 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -189,8 +189,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -311,6 +311,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-5.15/x86-kmsan-don-t-instrument-stack-walking-functions.patch b/queue-5.15/x86-kmsan-don-t-instrument-stack-walking-functions.patch new file mode 100644 index 0000000000..640da1336d --- /dev/null +++ b/queue-5.15/x86-kmsan-don-t-instrument-stack-walking-functions.patch @@ -0,0 +1,116 @@ +From fb30f59769bda8aa8d73738f9c7cfbbf35f31290 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 17:04:13 +0200 +Subject: x86: kmsan: don't instrument stack walking functions + +From: Alexander Potapenko + +[ Upstream commit 37ad4ee8364255c73026a3c343403b5977fa7e79 ] + +Upon function exit, KMSAN marks local variables as uninitialized. Further +function calls may result in the compiler creating the stack frame where +these local variables resided. This results in frame pointers being +marked as uninitialized data, which is normally correct, because they are +not stack-allocated. + +However stack unwinding functions are supposed to read and dereference the +frame pointers, in which case KMSAN might be reporting uses of +uninitialized values. + +To work around that, we mark update_stack_state(), unwind_next_frame() and +show_trace_log_lvl() with __no_kmsan_checks, preventing all KMSAN reports +inside those functions and making them return initialized values. + +Link: https://lkml.kernel.org/r/20220915150417.722975-40-glider@google.com +Signed-off-by: Alexander Potapenko +Cc: Alexander Viro +Cc: Alexei Starovoitov +Cc: Andrey Konovalov +Cc: Andrey Konovalov +Cc: Andy Lutomirski +Cc: Arnd Bergmann +Cc: Borislav Petkov +Cc: Christoph Hellwig +Cc: Christoph Lameter +Cc: David Rientjes +Cc: Dmitry Vyukov +Cc: Eric Biggers +Cc: Eric Biggers +Cc: Eric Dumazet +Cc: Greg Kroah-Hartman +Cc: Herbert Xu +Cc: Ilya Leoshkevich +Cc: Ingo Molnar +Cc: Jens Axboe +Cc: Joonsoo Kim +Cc: Kees Cook +Cc: Marco Elver +Cc: Mark Rutland +Cc: Matthew Wilcox +Cc: Michael S. Tsirkin +Cc: Pekka Enberg +Cc: Peter Zijlstra +Cc: Petr Mladek +Cc: Stephen Rothwell +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Vasily Gorbik +Cc: Vegard Nossum +Cc: Vlastimil Babka +Signed-off-by: Andrew Morton +Stable-dep-of: ced37e9ceae5 ("x86/dumpstack: Prevent KASAN false positive warnings in __show_regs()") +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 6 ++++++ + arch/x86/kernel/unwind_frame.c | 11 +++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 8a8660074284f..4adbc85b74a33 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,6 +183,12 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + } + } + ++/* ++ * This function reads pointers from the stack and dereferences them. The ++ * pointers may not have their KMSAN shadow set up properly, which may result ++ * in false positive reports. Disable instrumentation to avoid those. ++ */ ++__no_kmsan_checks + static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + unsigned long *stack, const char *log_lvl) + { +diff --git a/arch/x86/kernel/unwind_frame.c b/arch/x86/kernel/unwind_frame.c +index d7c44b257f7f4..8943114f9ebed 100644 +--- a/arch/x86/kernel/unwind_frame.c ++++ b/arch/x86/kernel/unwind_frame.c +@@ -183,6 +183,16 @@ static struct pt_regs *decode_frame_pointer(unsigned long *bp) + } + #endif + ++/* ++ * While walking the stack, KMSAN may stomp on stale locals from other ++ * functions that were marked as uninitialized upon function exit, and ++ * now hold the call frame information for the current function (e.g. the frame ++ * pointer). Because KMSAN does not specifically mark call frames as ++ * initialized, false positive reports are possible. To prevent such reports, ++ * we mark the functions scanning the stack (here and below) with ++ * __no_kmsan_checks. ++ */ ++__no_kmsan_checks + static bool update_stack_state(struct unwind_state *state, + unsigned long *next_bp) + { +@@ -251,6 +261,7 @@ static bool update_stack_state(struct unwind_state *state, + return true; + } + ++__no_kmsan_checks + bool unwind_next_frame(struct unwind_state *state) + { + struct pt_regs *regs; +-- +2.51.0 + diff --git a/queue-6.1/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-6.1/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..5e0912cf0c --- /dev/null +++ b/queue-6.1/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 74fb2caf3876397b44c550576b7dc533b3e0a102 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 2ac48cda5b201..eae7efae3b5cf 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-6.1/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-6.1/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..bfc1c3bc6e --- /dev/null +++ b/queue-6.1/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 04b945802db3b0ae0b3d81fef071be499a8fd6da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 9f7880cc2bd8c..0ff1c3d2504d4 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1634,6 +1634,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.1/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-6.1/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..22d0e21c1b --- /dev/null +++ b/queue-6.1/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From 1f268315a3aac9cbb739a61d16b5b47a8ef703d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 41d0de6a7027b..9b7e2b85004a9 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -338,17 +338,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_xcvr-add-counter-registers.patch b/queue-6.1/asoc-fsl_xcvr-add-counter-registers.patch new file mode 100644 index 0000000000..23e15057a8 --- /dev/null +++ b/queue-6.1/asoc-fsl_xcvr-add-counter-registers.patch @@ -0,0 +1,156 @@ +From be6b70dc6b0b34d21f4caa4b4782185af1c799b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Oct 2022 15:03:47 +0800 +Subject: ASoC: fsl_xcvr: Add Counter registers + +From: Shengjiu Wang + +[ Upstream commit 107d170dc46e14cfa575d1b995107ef2f2e51dfe ] + +These counter registers are part of register list, +add them to complete the register map + +- DMAC counter control registers +- Data path Timestamp counter register +- Data path bit counter register +- Data path bit count timestamp register +- Data path bit read timestamp register + +Signed-off-by: Shengjiu Wang +Link: https://lore.kernel.org/r/1666940627-7611-1-git-send-email-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 40 ++++++++++++++++++++++++++++++++++++++++ + sound/soc/fsl/fsl_xcvr.h | 21 +++++++++++++++++++++ + 2 files changed, 61 insertions(+) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 4c5864e8267d0..6c8a2519cc1bd 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -934,6 +934,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_TSCR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCTR, 0x00000000 }, ++ { FSL_XCVR_RX_DPTH_BCRR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL_SET, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CTRL_CLR, 0x00000000 }, +@@ -944,6 +952,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_TX_CS_DATA_3, 0x00000000 }, + { FSL_XCVR_TX_CS_DATA_4, 0x00000000 }, + { FSL_XCVR_TX_CS_DATA_5, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_SET, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_TSCR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCTR, 0x00000000 }, ++ { FSL_XCVR_TX_DPTH_BCRR, 0x00000000 }, + { FSL_XCVR_DEBUG_REG_0, 0x00000000 }, + { FSL_XCVR_DEBUG_REG_1, 0x00000000 }, + }; +@@ -975,6 +991,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_TSCR: ++ case FSL_XCVR_RX_DPTH_BCR: ++ case FSL_XCVR_RX_DPTH_BCTR: ++ case FSL_XCVR_RX_DPTH_BCRR: + case FSL_XCVR_TX_DPTH_CTRL: + case FSL_XCVR_TX_DPTH_CTRL_SET: + case FSL_XCVR_TX_DPTH_CTRL_CLR: +@@ -985,6 +1009,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_TX_CS_DATA_3: + case FSL_XCVR_TX_CS_DATA_4: + case FSL_XCVR_TX_CS_DATA_5: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: ++ case FSL_XCVR_TX_DPTH_TSCR: ++ case FSL_XCVR_TX_DPTH_BCR: ++ case FSL_XCVR_TX_DPTH_BCTR: ++ case FSL_XCVR_TX_DPTH_BCRR: + case FSL_XCVR_DEBUG_REG_0: + case FSL_XCVR_DEBUG_REG_1: + return true; +@@ -1017,6 +1049,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: + case FSL_XCVR_TX_DPTH_CTRL_SET: + case FSL_XCVR_TX_DPTH_CTRL_CLR: + case FSL_XCVR_TX_DPTH_CTRL_TOG: +@@ -1026,6 +1062,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_TX_CS_DATA_3: + case FSL_XCVR_TX_CS_DATA_4: + case FSL_XCVR_TX_CS_DATA_5: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: ++ case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: + return true; + default: + return false; +diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h +index 7f2853c60085e..4769b0fca21de 100644 +--- a/sound/soc/fsl/fsl_xcvr.h ++++ b/sound/soc/fsl/fsl_xcvr.h +@@ -49,6 +49,16 @@ + #define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188 + #define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c + ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 ++#define FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG 0x1CC ++ ++#define FSL_XCVR_RX_DPTH_TSCR 0x1D0 ++#define FSL_XCVR_RX_DPTH_BCR 0x1D4 ++#define FSL_XCVR_RX_DPTH_BCTR 0x1D8 ++#define FSL_XCVR_RX_DPTH_BCRR 0x1DC ++ + #define FSL_XCVR_TX_DPTH_CTRL 0x220 /* TX datapath ctrl reg */ + #define FSL_XCVR_TX_DPTH_CTRL_SET 0x224 + #define FSL_XCVR_TX_DPTH_CTRL_CLR 0x228 +@@ -59,6 +69,17 @@ + #define FSL_XCVR_TX_CS_DATA_3 0x23C + #define FSL_XCVR_TX_CS_DATA_4 0x240 + #define FSL_XCVR_TX_CS_DATA_5 0x244 ++ ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL 0x260 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_SET 0x264 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR 0x268 ++#define FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG 0x26C ++ ++#define FSL_XCVR_TX_DPTH_TSCR 0x270 ++#define FSL_XCVR_TX_DPTH_BCR 0x274 ++#define FSL_XCVR_TX_DPTH_BCTR 0x278 ++#define FSL_XCVR_TX_DPTH_BCRR 0x27C ++ + #define FSL_XCVR_DEBUG_REG_0 0x2E0 + #define FSL_XCVR_DEBUG_REG_1 0x2F0 + +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch b/queue-6.1/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch new file mode 100644 index 0000000000..553ab9a512 --- /dev/null +++ b/queue-6.1/asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch @@ -0,0 +1,316 @@ +From fb67237353b02a20694f939f2877832c521d99e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Jan 2023 10:39:52 +0800 +Subject: ASoC: fsl_xcvr: Add support for i.MX93 platform + +From: Chancel Liu + +[ Upstream commit e240b9329a300af7b7c1eba2ce0abbf19e6c540b ] + +Add compatible string and specific soc data to support XCVR on i.MX93 +platform. XCVR IP on i.MX93 is cut to SPDIF only by removing external +PHY. + +Signed-off-by: Chancel Liu +Acked-by: Shengjiu Wang +Link: https://lore.kernel.org/r/20230104023953.2973362-3-chancel.liu@nxp.com +Signed-off-by: Mark Brown +Stable-dep-of: 73b97d46dde6 ("ASoC: fsl_xcvr: clear the channel status control memory") +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 143 ++++++++++++++++++++++++++------------- + sound/soc/fsl/fsl_xcvr.h | 7 ++ + 2 files changed, 102 insertions(+), 48 deletions(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 6c8a2519cc1bd..8f8ff0ff9765a 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -21,6 +21,7 @@ + + struct fsl_xcvr_soc_data { + const char *fw_name; ++ bool spdif_only; + }; + + struct fsl_xcvr { +@@ -261,6 +262,9 @@ static int fsl_xcvr_en_phy_pll(struct fsl_xcvr *xcvr, u32 freq, bool tx) + u32 i, div = 0, log2; + int ret; + ++ if (xcvr->soc_data->spdif_only) ++ return 0; ++ + for (i = 0; i < ARRAY_SIZE(fsl_xcvr_pll_cfg); i++) { + if (fsl_xcvr_pll_cfg[i].fout % freq == 0) { + div = fsl_xcvr_pll_cfg[i].fout / freq; +@@ -353,6 +357,7 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq) + struct device *dev = &xcvr->pdev->dev; + int ret; + ++ freq = xcvr->soc_data->spdif_only ? freq / 10 : freq; + clk_disable_unprepare(xcvr->phy_clk); + ret = clk_set_rate(xcvr->phy_clk, freq); + if (ret < 0) { +@@ -365,6 +370,8 @@ static int fsl_xcvr_en_aud_pll(struct fsl_xcvr *xcvr, u32 freq) + return ret; + } + ++ if (xcvr->soc_data->spdif_only) ++ return 0; + /* Release AI interface from reset */ + ret = regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, + FSL_XCVR_PHY_AI_CTRL_AI_RESETN); +@@ -547,10 +554,12 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream, + + xcvr->streams |= BIT(substream->stream); + +- /* Disable XCVR controls if there is stream started */ +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, false); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, false); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, false); ++ if (!xcvr->soc_data->spdif_only) { ++ /* Disable XCVR controls if there is stream started */ ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, false); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, false); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, false); ++ } + + return 0; + } +@@ -567,12 +576,13 @@ static void fsl_xcvr_shutdown(struct snd_pcm_substream *substream, + + /* Enable XCVR controls if there is no stream started */ + if (!xcvr->streams) { +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, true); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, +- (xcvr->mode == FSL_XCVR_MODE_ARC)); +- fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, +- (xcvr->mode == FSL_XCVR_MODE_EARC)); +- ++ if (!xcvr->soc_data->spdif_only) { ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_mode_kctl.name, true); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_arc_mode_kctl.name, ++ (xcvr->mode == FSL_XCVR_MODE_ARC)); ++ fsl_xcvr_activate_ctl(dai, fsl_xcvr_earc_capds_kctl.name, ++ (xcvr->mode == FSL_XCVR_MODE_EARC)); ++ } + ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0, + FSL_XCVR_IRQ_EARC_ALL, 0); + if (ret < 0) { +@@ -673,7 +683,10 @@ static int fsl_xcvr_trigger(struct snd_pcm_substream *substream, int cmd, + dev_err(dai->dev, "Failed to stop DATA_TX: %d\n", ret); + return ret; + } +- fallthrough; ++ if (xcvr->soc_data->spdif_only) ++ break; ++ else ++ fallthrough; + case FSL_XCVR_MODE_EARC: + /* clear ISR_CMDC_TX_EN, W1C */ + ret = regmap_write(xcvr->regmap, +@@ -870,9 +883,13 @@ static int fsl_xcvr_dai_probe(struct snd_soc_dai *dai) + + snd_soc_dai_init_dma_data(dai, &xcvr->dma_prms_tx, &xcvr->dma_prms_rx); + +- snd_soc_add_dai_controls(dai, &fsl_xcvr_mode_kctl, 1); +- snd_soc_add_dai_controls(dai, &fsl_xcvr_arc_mode_kctl, 1); +- snd_soc_add_dai_controls(dai, &fsl_xcvr_earc_capds_kctl, 1); ++ if (xcvr->soc_data->spdif_only) ++ xcvr->mode = FSL_XCVR_MODE_SPDIF; ++ else { ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_mode_kctl, 1); ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_arc_mode_kctl, 1); ++ snd_soc_add_dai_controls(dai, &fsl_xcvr_earc_capds_kctl, 1); ++ } + snd_soc_add_dai_controls(dai, fsl_xcvr_tx_ctls, + ARRAY_SIZE(fsl_xcvr_tx_ctls)); + snd_soc_add_dai_controls(dai, fsl_xcvr_rx_ctls, +@@ -930,10 +947,11 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + { FSL_XCVR_ISR_SET, 0x00000000 }, + { FSL_XCVR_ISR_CLR, 0x00000000 }, + { FSL_XCVR_ISR_TOG, 0x00000000 }, +- { FSL_XCVR_RX_DPTH_CTRL, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, +- { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, ++ { FSL_XCVR_CLK_CTRL, 0x0000018F }, ++ { FSL_XCVR_RX_DPTH_CTRL, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00040CC1 }, ++ { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00040CC1 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, +@@ -966,6 +984,12 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { + + static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + { ++ struct fsl_xcvr *xcvr = dev_get_drvdata(dev); ++ ++ if (xcvr->soc_data->spdif_only) ++ if ((reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA) || ++ reg > FSL_XCVR_TX_DPTH_BCRR) ++ return false; + switch (reg) { + case FSL_XCVR_VERSION: + case FSL_XCVR_EXT_CTRL: +@@ -991,6 +1015,12 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + case FSL_XCVR_RX_DPTH_CTRL_SET: + case FSL_XCVR_RX_DPTH_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CTRL_TOG: ++ case FSL_XCVR_RX_CS_DATA_0: ++ case FSL_XCVR_RX_CS_DATA_1: ++ case FSL_XCVR_RX_CS_DATA_2: ++ case FSL_XCVR_RX_CS_DATA_3: ++ case FSL_XCVR_RX_CS_DATA_4: ++ case FSL_XCVR_RX_CS_DATA_5: + case FSL_XCVR_RX_DPTH_CNTR_CTRL: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: +@@ -1027,6 +1057,11 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) + + static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) + { ++ struct fsl_xcvr *xcvr = dev_get_drvdata(dev); ++ ++ if (xcvr->soc_data->spdif_only) ++ if (reg >= FSL_XCVR_IER && reg <= FSL_XCVR_PHY_AI_RDATA) ++ return false; + switch (reg) { + case FSL_XCVR_EXT_CTRL: + case FSL_XCVR_EXT_IER0: +@@ -1103,32 +1138,34 @@ static irqreturn_t irq0_isr(int irq, void *devid) + if (isr & FSL_XCVR_IRQ_NEW_CS) { + dev_dbg(dev, "Received new CS block\n"); + isr_clr |= FSL_XCVR_IRQ_NEW_CS; +- /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ +- regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, +- FSL_XCVR_EXT_CTRL_PAGE_MASK, +- FSL_XCVR_EXT_CTRL_PAGE(8)); +- +- /* Find updated CS buffer */ +- reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_0; +- reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_0; +- memcpy_fromio(&val, reg_ctrl, sizeof(val)); +- if (!val) { +- reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_1; +- reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_1; ++ if (!xcvr->soc_data->spdif_only) { ++ /* Data RAM is 4KiB, last two pages: 8 and 9. Select page 8. */ ++ regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, ++ FSL_XCVR_EXT_CTRL_PAGE_MASK, ++ FSL_XCVR_EXT_CTRL_PAGE(8)); ++ ++ /* Find updated CS buffer */ ++ reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_0; ++ reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_0; + memcpy_fromio(&val, reg_ctrl, sizeof(val)); +- } ++ if (!val) { ++ reg_ctrl = xcvr->ram_addr + FSL_XCVR_RX_CS_CTRL_1; ++ reg_buff = xcvr->ram_addr + FSL_XCVR_RX_CS_BUFF_1; ++ memcpy_fromio(&val, reg_ctrl, sizeof(val)); ++ } + +- if (val) { +- /* copy CS buffer */ +- memcpy_fromio(&xcvr->rx_iec958.status, reg_buff, +- sizeof(xcvr->rx_iec958.status)); +- for (i = 0; i < 6; i++) { +- val = *(u32 *)(xcvr->rx_iec958.status + i*4); +- *(u32 *)(xcvr->rx_iec958.status + i*4) = +- bitrev32(val); ++ if (val) { ++ /* copy CS buffer */ ++ memcpy_fromio(&xcvr->rx_iec958.status, reg_buff, ++ sizeof(xcvr->rx_iec958.status)); ++ for (i = 0; i < 6; i++) { ++ val = *(u32 *)(xcvr->rx_iec958.status + i*4); ++ *(u32 *)(xcvr->rx_iec958.status + i*4) = ++ bitrev32(val); ++ } ++ /* clear CS control register */ ++ memset_io(reg_ctrl, 0, sizeof(val)); + } +- /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); + } + } + if (isr & FSL_XCVR_IRQ_NEW_UD) { +@@ -1168,8 +1205,13 @@ static const struct fsl_xcvr_soc_data fsl_xcvr_imx8mp_data = { + .fw_name = "imx/xcvr/xcvr-imx8mp.bin", + }; + ++static const struct fsl_xcvr_soc_data fsl_xcvr_imx93_data = { ++ .spdif_only = true, ++}; ++ + static const struct of_device_id fsl_xcvr_dt_ids[] = { + { .compatible = "fsl,imx8mp-xcvr", .data = &fsl_xcvr_imx8mp_data }, ++ { .compatible = "fsl,imx93-xcvr", .data = &fsl_xcvr_imx93_data}, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, fsl_xcvr_dt_ids); +@@ -1229,7 +1271,7 @@ static int fsl_xcvr_probe(struct platform_device *pdev) + return PTR_ERR(xcvr->regmap); + } + +- xcvr->reset = devm_reset_control_get_exclusive(dev, NULL); ++ xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(xcvr->reset)) { + dev_err(dev, "failed to get XCVR reset control\n"); + return PTR_ERR(xcvr->reset); +@@ -1306,12 +1348,14 @@ static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev) + if (ret < 0) + dev_err(dev, "Failed to clear IER0: %d\n", ret); + +- /* Assert M0+ reset */ +- ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, +- FSL_XCVR_EXT_CTRL_CORE_RESET, +- FSL_XCVR_EXT_CTRL_CORE_RESET); +- if (ret < 0) +- dev_err(dev, "Failed to assert M0+ core: %d\n", ret); ++ if (!xcvr->soc_data->spdif_only) { ++ /* Assert M0+ reset */ ++ ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL, ++ FSL_XCVR_EXT_CTRL_CORE_RESET, ++ FSL_XCVR_EXT_CTRL_CORE_RESET); ++ if (ret < 0) ++ dev_err(dev, "Failed to assert M0+ core: %d\n", ret); ++ } + + regcache_cache_only(xcvr->regmap, true); + +@@ -1367,6 +1411,9 @@ static __maybe_unused int fsl_xcvr_runtime_resume(struct device *dev) + goto stop_spba_clk; + } + ++ if (xcvr->soc_data->spdif_only) ++ return 0; ++ + ret = reset_control_deassert(xcvr->reset); + if (ret) { + dev_err(dev, "failed to deassert M0+ reset.\n"); +diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h +index 4769b0fca21de..044058fc6aa24 100644 +--- a/sound/soc/fsl/fsl_xcvr.h ++++ b/sound/soc/fsl/fsl_xcvr.h +@@ -49,6 +49,13 @@ + #define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188 + #define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c + ++#define FSL_XCVR_RX_CS_DATA_0 0x190 ++#define FSL_XCVR_RX_CS_DATA_1 0x194 ++#define FSL_XCVR_RX_CS_DATA_2 0x198 ++#define FSL_XCVR_RX_CS_DATA_3 0x19C ++#define FSL_XCVR_RX_CS_DATA_4 0x1A0 ++#define FSL_XCVR_RX_CS_DATA_5 0x1A4 ++ + #define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 + #define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 + #define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-6.1/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..b336caf07d --- /dev/null +++ b/queue-6.1/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From d72246e6214a0533c9dc9ed97d5daec09c120a9d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 8f8ff0ff9765a..9093f3e6e1962 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1164,7 +1164,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } + } +-- +2.51.0 + diff --git a/queue-6.1/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-6.1/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..b0bf33f3bd --- /dev/null +++ b/queue-6.1/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From c8cf200ba0f8f168241da131a2703b93bc4a7e33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index 30ca5416c9a3f..a30cdc94871d1 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-6.1/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-6.1/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..301bbdb8e2 --- /dev/null +++ b/queue-6.1/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 6d620ea4953ae8e2d67cc6f9acdee82bd09b948c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index d360def24747d..223f078acfd9f 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-6.1/backlight-led_bl-take-led_access-lock-when-required.patch b/queue-6.1/backlight-led_bl-take-led_access-lock-when-required.patch new file mode 100644 index 0000000000..929ada1458 --- /dev/null +++ b/queue-6.1/backlight-led_bl-take-led_access-lock-when-required.patch @@ -0,0 +1,73 @@ +From fb6780d75751999d9e1108b1b290fece1a833861 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Jun 2023 17:02:49 +0100 +Subject: backlight: led_bl: Take led_access lock when required + +From: Mans Rullgard + +[ Upstream commit a33677b9211b6c328ad359b072043af94f7c9592 ] + +The led_access lock must be held when calling led_sysfs_enable() and +led_sysfs_disable(). This fixes warnings such as this: + +[ 2.432495] ------------[ cut here ]------------ +[ 2.437316] WARNING: CPU: 0 PID: 22 at drivers/leds/led-core.c:349 led_sysfs_disable+0x54/0x58 +[ 2.446105] Modules linked in: +[ 2.449218] CPU: 0 PID: 22 Comm: kworker/u2:1 Not tainted 6.3.8+ #1 +[ 2.456268] Hardware name: Generic AM3517 (Flattened Device Tree) +[ 2.462402] Workqueue: events_unbound deferred_probe_work_func +[ 2.468353] unwind_backtrace from show_stack+0x10/0x14 +[ 2.473632] show_stack from dump_stack_lvl+0x24/0x2c +[ 2.478759] dump_stack_lvl from __warn+0x9c/0xc4 +[ 2.483551] __warn from warn_slowpath_fmt+0x64/0xc0 +[ 2.488586] warn_slowpath_fmt from led_sysfs_disable+0x54/0x58 +[ 2.494567] led_sysfs_disable from led_bl_probe+0x20c/0x3b0 +[ 2.500305] led_bl_probe from platform_probe+0x5c/0xb8 +[ 2.505615] platform_probe from really_probe+0xc8/0x2a0 +[ 2.510986] really_probe from __driver_probe_device+0x88/0x19c +[ 2.516967] __driver_probe_device from driver_probe_device+0x30/0xcc +[ 2.523498] driver_probe_device from __device_attach_driver+0x94/0xc4 +[ 2.530090] __device_attach_driver from bus_for_each_drv+0x80/0xcc +[ 2.536437] bus_for_each_drv from __device_attach+0xf8/0x19c +[ 2.542236] __device_attach from bus_probe_device+0x8c/0x90 +[ 2.547973] bus_probe_device from deferred_probe_work_func+0x80/0xb0 +[ 2.554504] deferred_probe_work_func from process_one_work+0x228/0x4c0 +[ 2.561187] process_one_work from worker_thread+0x1fc/0x4d0 +[ 2.566925] worker_thread from kthread+0xb4/0xd0 +[ 2.571685] kthread from ret_from_fork+0x14/0x2c +[ 2.576446] Exception stack(0xd0079fb0 to 0xd0079ff8) +[ 2.581573] 9fa0: 00000000 00000000 00000000 00000000 +[ 2.589813] 9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +[ 2.598052] 9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 +[ 2.604888] ---[ end trace 0000000000000000 ]--- + +Signed-off-by: Mans Rullgard +Reviewed-by: Daniel Thompson +Link: https://lore.kernel.org/r/20230619160249.10414-1-mans@mansr.com +Signed-off-by: Lee Jones +Stable-dep-of: 9341d6698f4c ("backlight: led-bl: Add devlink to supplier LEDs") +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 589dae9ebb638..d360def24747d 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,8 +209,11 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + +- for (i = 0; i < priv->nb_leds; i++) ++ for (i = 0; i < priv->nb_leds; i++) { ++ mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); ++ mutex_unlock(&priv->leds[i]->led_access); ++ } + + backlight_update_status(priv->bl_dev); + +-- +2.51.0 + diff --git a/queue-6.1/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-6.1/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..0015fee7bb --- /dev/null +++ b/queue-6.1/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From a93bb92307f5b091e90c9751c7f32d1c8ca40909 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-6.1/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch b/queue-6.1/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch new file mode 100644 index 0000000000..de8a6aecc9 --- /dev/null +++ b/queue-6.1/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch @@ -0,0 +1,69 @@ +From 1e580993fa2368935549fe4275f9da2078cf0081 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:23:30 -0800 +Subject: bpf: Check skb->transport_header is set in bpf_skb_check_mtu + +From: Martin KaFai Lau + +[ Upstream commit d946f3c98328171fa50ddb908593cf833587f725 ] + +The bpf_skb_check_mtu helper needs to use skb->transport_header when +the BPF_MTU_CHK_SEGS flag is used: + + bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) + +The transport_header is not always set. There is a WARN_ON_ONCE +report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + +bpf_prog_test_run is used: + +WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 + skb_gso_validate_network_len + bpf_skb_check_mtu + bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch + bpf_test_run + bpf_prog_test_run_skb + +For a normal ingress skb (not test_run), skb_reset_transport_header +is performed but there is plan to avoid setting it as described in +commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). + +This patch fixes the bpf helper by checking +skb_transport_header_was_set(). The check is done just before +skb->transport_header is used, to avoid breaking the existing bpf prog. +The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. + +Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") +Cc: Jesper Dangaard Brouer +Reported-by: Kaiyan Mei +Reported-by: Yinhao Hu +Signed-off-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 786064ac889a1..ac84e70cf5436 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -6206,9 +6206,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, + */ + if (skb_is_gso(skb)) { + ret = BPF_MTU_CHK_RET_SUCCESS; +- if (flags & BPF_MTU_CHK_SEGS && +- !skb_gso_validate_network_len(skb, mtu)) +- ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ if (flags & BPF_MTU_CHK_SEGS) { ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ if (!skb_gso_validate_network_len(skb, mtu)) ++ ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ } + } + out: + *mtu_len = mtu; +-- +2.51.0 + diff --git a/queue-6.1/bpf-fix-invalid-prog-stats-access-when-update_effect.patch b/queue-6.1/bpf-fix-invalid-prog-stats-access-when-update_effect.patch new file mode 100644 index 0000000000..9c82e772da --- /dev/null +++ b/queue-6.1/bpf-fix-invalid-prog-stats-access-when-update_effect.patch @@ -0,0 +1,91 @@ +From c7e7279dd557b13b59f43fb025ad1d685429b549 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:23:43 +0000 +Subject: bpf: Fix invalid prog->stats access when update_effective_progs fails + +From: Pu Lehui + +[ Upstream commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc ] + +Syzkaller triggers an invalid memory access issue following fault +injection in update_effective_progs. The issue can be described as +follows: + +__cgroup_bpf_detach + update_effective_progs + compute_effective_progs + bpf_prog_array_alloc <-- fault inject + purge_effective_progs + /* change to dummy_bpf_prog */ + array->items[index] = &dummy_bpf_prog.prog + +---softirq start--- +__do_softirq + ... + __cgroup_bpf_run_filter_skb + __bpf_prog_run_save_cb + bpf_prog_run + stats = this_cpu_ptr(prog->stats) + /* invalid memory access */ + flags = u64_stats_update_begin_irqsave(&stats->syncp) +---softirq end--- + + static_branch_dec(&cgroup_bpf_enabled_key[atype]) + +The reason is that fault injection caused update_effective_progs to fail +and then changed the original prog into dummy_bpf_prog.prog in +purge_effective_progs. Then a softirq came, and accessing the members of +dummy_bpf_prog.prog in the softirq triggers invalid mem access. + +To fix it, skip updating stats when stats is NULL. + +Fixes: 492ecee892c2 ("bpf: enable program stats") +Signed-off-by: Pu Lehui +Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 12 +++++++----- + kernel/bpf/syscall.c | 3 +++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index b7de1cbda5dc5..37260c48fad49 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -596,11 +596,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; +- stats = this_cpu_ptr(prog->stats); +- flags = u64_stats_update_begin_irqsave(&stats->syncp); +- u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, duration); +- u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ if (likely(prog->stats)) { ++ stats = this_cpu_ptr(prog->stats); ++ flags = u64_stats_update_begin_irqsave(&stats->syncp); ++ u64_stats_inc(&stats->cnt); ++ u64_stats_add(&stats->nsecs, duration); ++ u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ } + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index c15d243bfe382..b559d99e5959a 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2141,6 +2141,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) + struct bpf_prog_stats *stats; + unsigned int flags; + ++ if (unlikely(!prog->stats)) ++ return; ++ + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); +-- +2.51.0 + diff --git a/queue-6.1/bpf-improve-program-stats-run-time-calculation.patch b/queue-6.1/bpf-improve-program-stats-run-time-calculation.patch new file mode 100644 index 0000000000..259f520bee --- /dev/null +++ b/queue-6.1/bpf-improve-program-stats-run-time-calculation.patch @@ -0,0 +1,85 @@ +From de2fd52a67e2b89baf6d2fb5d2b5f4c4e41ebd9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 21:40:10 -0600 +Subject: bpf: Improve program stats run-time calculation + +From: Jose Fernandez + +[ Upstream commit ce09cbdd988887662546a1175bcfdfc6c8fdd150 ] + +This patch improves the run-time calculation for program stats by +capturing the duration as soon as possible after the program returns. + +Previously, the duration included u64_stats_t operations. While the +instrumentation overhead is part of the total time spent when stats are +enabled, distinguishing between the program's native execution time and +the time spent due to instrumentation is crucial for accurate +performance analysis. + +By making this change, the patch facilitates more precise optimization +of BPF programs, enabling users to understand their performance in +environments without stats enabled. + +I used a virtualized environment to measure the run-time over one minute +for a basic raw_tracepoint/sys_enter program, which just increments a +local counter. Although the virtualization introduced some performance +degradation that could affect the results, I observed approximately a +16% decrease in average run-time reported by stats with this change +(310 -> 260 nsec). + +Signed-off-by: Jose Fernandez +Signed-off-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240402034010.25060-1-josef@netflix.com +Stable-dep-of: 7dc211c1159d ("bpf: Fix invalid prog->stats access when update_effective_progs fails") +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 6 ++++-- + kernel/bpf/trampoline.c | 3 ++- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index 502cab01e9e97..b7de1cbda5dc5 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -590,14 +590,16 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + cant_migrate(); + if (static_branch_unlikely(&bpf_stats_enabled_key)) { + struct bpf_prog_stats *stats; +- u64 start = sched_clock(); ++ u64 duration, start = sched_clock(); + unsigned long flags; + + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); ++ ++ duration = sched_clock() - start; + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index 748ac86169941..4c7c6129db90e 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -901,12 +901,13 @@ static void notrace update_prog_stats(struct bpf_prog *prog, + * Hence check that 'start' is valid. + */ + start > NO_START_TIME) { ++ u64 duration = sched_clock() - start; + unsigned long flags; + + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } + } +-- +2.51.0 + diff --git a/queue-6.1/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch b/queue-6.1/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch new file mode 100644 index 0000000000..d8791df8e1 --- /dev/null +++ b/queue-6.1/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch @@ -0,0 +1,58 @@ +From 8691fb8ebfabd3885470df2e5a053d72d3543b6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 05:04:43 +0200 +Subject: clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle + callback + +From: Marek Vasut + +[ Upstream commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab ] + +R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page +583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) +indicate after reset has been asserted by writing a matching reset bit +into register SRCR, it is mandatory to wait 1ms. + +This 1ms delay is documented on R-Car V4H and V4M, it is currently +unclear whether S4 is affected as well. This patch does apply the extra +delay on R-Car S4 as well. + +Fix the reset driver to respect the additional delay when toggling +resets. Drivers which use separate reset_control_(de)assert() must +assure matching delay in their driver code. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 523fd45231571..d6137379510c1 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -618,8 +618,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + /* Reset module */ + writel(bitmask, priv->base + priv->reset_regs[reg]); + +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); ++ /* ++ * On R-Car Gen4, delay after SRCR has been written is 1ms. ++ * On older SoCs, delay after SRCR has been written is 35us ++ * (one cycle of the RCLK clock @ ca. 32 kHz). ++ */ ++ if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) ++ usleep_range(1000, 2000); ++ else ++ usleep_range(35, 1000); + + /* Release module from reset state */ + writel(bitmask, priv->base + priv->reset_clear_regs[reg]); +-- +2.51.0 + diff --git a/queue-6.1/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-6.1/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..7d611f68ca --- /dev/null +++ b/queue-6.1/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From edcdc5427ebcb17b982dc00163909e4b54f6aa84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 087146f2ee068..4f9a11609a631 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -969,9 +969,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-6.1/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-6.1/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..942f3ec9bb --- /dev/null +++ b/queue-6.1/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From 72e7068e820eba2d791e6eaef9d940297da23898 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index b0185b4331523..0616efc7cb198 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -406,10 +406,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -858,11 +872,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-6.1/coresight-etm4x-correct-polling-idle-bit.patch b/queue-6.1/coresight-etm4x-correct-polling-idle-bit.patch new file mode 100644 index 0000000000..06eb8c83d5 --- /dev/null +++ b/queue-6.1/coresight-etm4x-correct-polling-idle-bit.patch @@ -0,0 +1,43 @@ +From fc40a8361eb2021ce9190fd6c23d1abda72b7ead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:38 +0000 +Subject: coresight: etm4x: Correct polling IDLE bit + +From: Leo Yan + +[ Upstream commit 4dc4e22f9536341255f5de6047977a80ff47eaef ] + +Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading +the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit +instead of the IDLE bit. + +This commit corrects the typo. + +Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") +Reviewed-by: Yeoreum Yun +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index d89153d0517ec..a3553f9ca0786 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1726,7 +1726,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +-- +2.51.0 + diff --git a/queue-6.1/coresight-etm4x-extract-the-trace-unit-controlling.patch b/queue-6.1/coresight-etm4x-extract-the-trace-unit-controlling.patch new file mode 100644 index 0000000000..5e38b8da01 --- /dev/null +++ b/queue-6.1/coresight-etm4x-extract-the-trace-unit-controlling.patch @@ -0,0 +1,171 @@ +From f78debf93fd1299478987ff028157c37b5e5e168 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 19:07:02 +0100 +Subject: coresight: etm4x: Extract the trace unit controlling + +From: Leo Yan + +[ Upstream commit 40f682ae5086366d51e29e66eb8a344501245d0d ] + +The trace unit is controlled in the ETM hardware enabling and disabling. +The sequential changes for support AUX pause and resume will reuse the +same operations. + +Extract the operations in the etm4_{enable|disable}_trace_unit() +functions. A minor improvement in etm4_enable_trace_unit() is for +returning the timeout error to callers. + +Signed-off-by: Leo Yan +Reviewed-by: Mike Leach +Reviewed-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250401180708.385396-2-leo.yan@arm.com +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 103 +++++++++++------- + 1 file changed, 62 insertions(+), 41 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index a3553f9ca0786..b0185b4331523 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -392,6 +392,44 @@ static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) + return coresight_timeout(csa, TRCSTATR, pos, val); + } + ++static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) ++{ ++ struct coresight_device *csdev = drvdata->csdev; ++ struct device *etm_dev = &csdev->dev; ++ struct csdev_access *csa = &csdev->access; ++ ++ /* ++ * ETE mandates that the TRCRSR is written to before ++ * enabling it. ++ */ ++ if (etm4x_is_ete(drvdata)) ++ etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); ++ ++ etm4x_allow_trace(drvdata); ++ /* Enable the trace unit */ ++ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); ++ ++ /* Synchronize the register updates for sysreg access */ ++ if (!csa->io_mem) ++ isb(); ++ ++ /* wait for TRCSTATR.IDLE to go back down to '0' */ ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) { ++ dev_err(etm_dev, ++ "timeout while waiting for Idle Trace Status\n"); ++ return -ETIME; ++ } ++ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using the ++ * memory-mapped interface") of ARM IHI 0064D ++ */ ++ dsb(sy); ++ isb(); ++ ++ return 0; ++} ++ + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + { + int i, rc; +@@ -501,33 +539,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); + } + +- /* +- * ETE mandates that the TRCRSR is written to before +- * enabling it. +- */ +- if (etm4x_is_ete(drvdata)) +- etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); +- +- etm4x_allow_trace(drvdata); +- /* Enable the trace unit */ +- etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); +- +- /* Synchronize the register updates for sysreg access */ +- if (!csa->io_mem) +- isb(); +- +- /* wait for TRCSTATR.IDLE to go back down to '0' */ +- if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) +- dev_err(etm_dev, +- "timeout while waiting for Idle Trace Status\n"); +- +- /* +- * As recommended by section 4.3.7 ("Synchronization when using the +- * memory-mapped interface") of ARM IHI 0064D +- */ +- dsb(sy); +- isb(); +- ++ rc = etm4_enable_trace_unit(drvdata); + done: + etm4_cs_lock(drvdata, csa); + +@@ -828,25 +840,12 @@ static int etm4_enable(struct coresight_device *csdev, + return ret; + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; +- struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct device *etm_dev = &csdev->dev; + struct csdev_access *csa = &csdev->access; +- int i; +- +- etm4_cs_unlock(drvdata, csa); +- etm4_disable_arch_specific(drvdata); +- +- if (!drvdata->skip_power_up) { +- /* power can be removed from the trace unit now */ +- control = etm4x_relaxed_read32(csa, TRCPDCR); +- control &= ~TRCPDCR_PU; +- etm4x_relaxed_write32(csa, control, TRCPDCR); +- } + + control = etm4x_relaxed_read32(csa, TRCPRGCTLR); + +@@ -887,6 +886,28 @@ static void etm4_disable_hw(void *info) + * of ARM IHI 0064H.b. + */ + isb(); ++} ++ ++static void etm4_disable_hw(void *info) ++{ ++ u32 control; ++ struct etmv4_drvdata *drvdata = info; ++ struct etmv4_config *config = &drvdata->config; ++ struct coresight_device *csdev = drvdata->csdev; ++ struct csdev_access *csa = &csdev->access; ++ int i; ++ ++ etm4_cs_unlock(drvdata, csa); ++ etm4_disable_arch_specific(drvdata); ++ ++ if (!drvdata->skip_power_up) { ++ /* power can be removed from the trace unit now */ ++ control = etm4x_relaxed_read32(csa, TRCPDCR); ++ control &= ~TRCPDCR_PU; ++ etm4x_relaxed_write32(csa, control, TRCPDCR); ++ } ++ ++ etm4_disable_trace_unit(drvdata); + + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { +-- +2.51.0 + diff --git a/queue-6.1/cpuset-treat-cpusets-in-attaching-as-populated.patch b/queue-6.1/cpuset-treat-cpusets-in-attaching-as-populated.patch new file mode 100644 index 0000000000..7b79a62b30 --- /dev/null +++ b/queue-6.1/cpuset-treat-cpusets-in-attaching-as-populated.patch @@ -0,0 +1,115 @@ +From 1b83544b9a0ff9184d2f15749fc6ba8c74e7791c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 02:08:47 +0000 +Subject: cpuset: Treat cpusets in attaching as populated + +From: Chen Ridong + +[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ] + +Currently, the check for whether a partition is populated does not +account for tasks in the cpuset of attaching. This is a corner case +that can leave a task stuck in a partition with no effective CPUs. + +The race condition occurs as follows: + +cpu0 cpu1 + //cpuset A with cpu N +migrate task p to A +cpuset_can_attach +// with effective cpus +// check ok + +// cpuset_mutex is not held // clear cpuset.cpus.exclusive + // making effective cpus empty + update_exclusive_cpumask + // tasks_nocpu_error check ok + // empty effective cpus, partition valid +cpuset_attach +... +// task p stays in A, with non-effective cpus. + +To fix this issue, this patch introduces cs_is_populated, which considers +tasks in the attaching cpuset. This new helper is used in validate_change +and partition_is_populated. + +Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") +Signed-off-by: Chen Ridong +Reviewed-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 216bdebd94264..d56433c8e970b 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -476,6 +476,15 @@ static inline bool is_in_v2_mode(void) + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); + } + ++static inline bool cpuset_is_populated(struct cpuset *cs) ++{ ++ lockdep_assert_held(&cpuset_mutex); ++ ++ /* Cpusets in the process of attaching should be considered as populated */ ++ return cgroup_is_populated(cs->css.cgroup) || ++ cs->attach_in_progress; ++} ++ + /** + * partition_is_populated - check if partition has tasks + * @cs: partition root to be checked +@@ -488,21 +497,31 @@ static inline bool is_in_v2_mode(void) + static inline bool partition_is_populated(struct cpuset *cs, + struct cpuset *excluded_child) + { +- struct cgroup_subsys_state *css; +- struct cpuset *child; ++ struct cpuset *cp; ++ struct cgroup_subsys_state *pos_css; + +- if (cs->css.cgroup->nr_populated_csets) ++ /* ++ * We cannot call cs_is_populated(cs) directly, as ++ * nr_populated_domain_children may include populated ++ * csets from descendants that are partitions. ++ */ ++ if (cs->css.cgroup->nr_populated_csets || ++ cs->attach_in_progress) + return true; + if (!excluded_child && !cs->nr_subparts_cpus) + return cgroup_is_populated(cs->css.cgroup); + + rcu_read_lock(); +- cpuset_for_each_child(child, css, cs) { +- if (child == excluded_child) ++ cpuset_for_each_descendant_pre(cp, pos_css, cs) { ++ if (cp == cs || cp == excluded_child) + continue; +- if (is_partition_valid(child)) ++ ++ if (is_partition_valid(cp)) { ++ pos_css = css_rightmost_descendant(pos_css); + continue; +- if (cgroup_is_populated(child->css.cgroup)) { ++ } ++ ++ if (cpuset_is_populated(cp)) { + rcu_read_unlock(); + return true; + } +@@ -774,7 +793,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) + * be changed to have empty cpus_allowed or mems_allowed. + */ + ret = -ENOSPC; +- if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { ++ if (cpuset_is_populated(cur)) { + if (!cpumask_empty(cur->cpus_allowed) && + cpumask_empty(trial->cpus_allowed)) + goto out; +-- +2.51.0 + diff --git a/queue-6.1/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-6.1/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..d7f03245e6 --- /dev/null +++ b/queue-6.1/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From a06863d9fd8dc6e8b33a15d5eb129789675956a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 3e4f5a361612d..9d144142e88e2 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -152,12 +153,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-6.1/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-6.1/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..0a1168fcef --- /dev/null +++ b/queue-6.1/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From 02e74eb440a4c1c3e1d1d870b497032c20c0b367 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index 9efd88f871d12..9ae2873219587 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-6.1/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-6.1/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..613e81caa8 --- /dev/null +++ b/queue-6.1/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From 9c1fbbdb29bc016ad9b07134f039997f7676ea87 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 42f1e7d0023e1..23fff5de3325a 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3450,6 +3450,7 @@ static int qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -3457,6 +3458,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -3470,11 +3472,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-6.1/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-6.1/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..8a3e258ba0 --- /dev/null +++ b/queue-6.1/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 4117c132a7e87bbb47604bb70c53c209d091ae31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 75e44d8a7b40f..f2d37572f2a69 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-6.1/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-6.1/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..bb71e489a6 --- /dev/null +++ b/queue-6.1/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From 9f684762c5c7b1f223810be1f9136760c7afeb13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 3a53ebc4e1724..2d090bdf5a009 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -85,27 +85,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -124,7 +103,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-6.1/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-6.1/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..eedd24ee91 --- /dev/null +++ b/queue-6.1/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From ad37ccb9e2bda77c6f75b56b06edf567ed780a62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index b380bbb0e0d0a..eb8bc6f6c118c 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -64,7 +64,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + int ret; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-6.1/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-6.1/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..665322bdc4 --- /dev/null +++ b/queue-6.1/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From 998ac93a9708ffe5f97b879642fc545d1d8d5518 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index e157541783959..d066345d5930b 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -94,7 +94,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.1/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-6.1/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..0c8a870e45 --- /dev/null +++ b/queue-6.1/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From 835157ca30e1916aed6ff2a852f56f092700e917 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index a5bd90bc0712e..9c3b8e65c42a3 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-6.1/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch b/queue-6.1/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch new file mode 100644 index 0000000000..3410acb221 --- /dev/null +++ b/queue-6.1/dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch @@ -0,0 +1,244 @@ +From 973c53abf05f39078a270e156abcb2e3c9b0a8bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Mar 2023 14:27:33 +0100 +Subject: dt-bindings: PCI: convert amlogic,meson-pcie.txt to dt-schema + +From: Neil Armstrong + +[ Upstream commit b80b848bdf56bd402b7a91aea5b77cec93dfe4c2 ] + +Convert the Amlogic Meson AXG DWC PCIe SoC controller bindings to +dt-schema. + +Link: https://lore.kernel.org/r/20221117-b4-amlogic-bindings-convert-v4-5-34e623dbf789@linaro.org +Signed-off-by: Neil Armstrong +Signed-off-by: Lorenzo Pieralisi +Reviewed-by: Krzysztof Kozlowski +Stable-dep-of: 4813dea9e272 ("dt-bindings: PCI: amlogic: Fix the register name of the DBI region") +Signed-off-by: Sasha Levin +--- + .../bindings/pci/amlogic,axg-pcie.yaml | 134 ++++++++++++++++++ + .../bindings/pci/amlogic,meson-pcie.txt | 70 --------- + 2 files changed, 134 insertions(+), 70 deletions(-) + create mode 100644 Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml + delete mode 100644 Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +new file mode 100644 +index 0000000000000..a5bd90bc0712e +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -0,0 +1,134 @@ ++# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) ++%YAML 1.2 ++--- ++$id: http://devicetree.org/schemas/pci/amlogic,axg-pcie.yaml# ++$schema: http://devicetree.org/meta-schemas/core.yaml# ++ ++title: Amlogic Meson AXG DWC PCIe SoC controller ++ ++maintainers: ++ - Neil Armstrong ++ ++description: ++ Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. ++ ++allOf: ++ - $ref: /schemas/pci/pci-bus.yaml# ++ - $ref: /schemas/pci/snps,dw-pcie-common.yaml# ++ ++# We need a select here so we don't match all nodes with 'snps,dw-pcie' ++select: ++ properties: ++ compatible: ++ enum: ++ - amlogic,axg-pcie ++ - amlogic,g12a-pcie ++ required: ++ - compatible ++ ++properties: ++ compatible: ++ items: ++ - enum: ++ - amlogic,axg-pcie ++ - amlogic,g12a-pcie ++ - const: snps,dw-pcie ++ ++ reg: ++ items: ++ - description: External local bus interface registers ++ - description: Meson designed configuration registers ++ - description: PCIe configuration space ++ ++ reg-names: ++ items: ++ - const: elbi ++ - const: cfg ++ - const: config ++ ++ interrupts: ++ maxItems: 1 ++ ++ clocks: ++ items: ++ - description: PCIe GEN 100M PLL clock ++ - description: PCIe RC clock gate ++ - description: PCIe PHY clock ++ ++ clock-names: ++ items: ++ - const: pclk ++ - const: port ++ - const: general ++ ++ phys: ++ maxItems: 1 ++ ++ phy-names: ++ const: pcie ++ ++ resets: ++ items: ++ - description: Port Reset ++ - description: Shared APB reset ++ ++ reset-names: ++ items: ++ - const: port ++ - const: apb ++ ++ num-lanes: ++ const: 1 ++ ++ power-domains: ++ maxItems: 1 ++ ++required: ++ - compatible ++ - reg ++ - reg-names ++ - interrupts ++ - clock ++ - clock-names ++ - "#address-cells" ++ - "#size-cells" ++ - "#interrupt-cells" ++ - interrupt-map ++ - interrupt-map-mask ++ - ranges ++ - bus-range ++ - device_type ++ - num-lanes ++ - phys ++ - phy-names ++ - resets ++ - reset-names ++ ++unevaluatedProperties: false ++ ++examples: ++ - | ++ #include ++ #include ++ pcie: pcie@f9800000 { ++ compatible = "amlogic,axg-pcie", "snps,dw-pcie"; ++ reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; ++ reg-names = "elbi", "cfg", "config"; ++ interrupts = ; ++ clocks = <&pclk>, <&clk_port>, <&clk_phy>; ++ clock-names = "pclk", "port", "general"; ++ resets = <&reset_pcie_port>, <&reset_pcie_apb>; ++ reset-names = "port", "apb"; ++ phys = <&pcie_phy>; ++ phy-names = "pcie"; ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; ++ bus-range = <0x0 0xff>; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ num-lanes = <1>; ++ ranges = <0x82000000 0 0 0xf9c00000 0 0x00300000>; ++ }; ++... +diff --git a/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt b/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt +deleted file mode 100644 +index c3a75ac6e59d1..0000000000000 +--- a/Documentation/devicetree/bindings/pci/amlogic,meson-pcie.txt ++++ /dev/null +@@ -1,70 +0,0 @@ +-Amlogic Meson AXG DWC PCIE SoC controller +- +-Amlogic Meson PCIe host controller is based on the Synopsys DesignWare PCI core. +-It shares common functions with the PCIe DesignWare core driver and +-inherits common properties defined in +-Documentation/devicetree/bindings/pci/snps,dw-pcie.yaml. +- +-Additional properties are described here: +- +-Required properties: +-- compatible: +- should contain : +- - "amlogic,axg-pcie" for AXG SoC Family +- - "amlogic,g12a-pcie" for G12A SoC Family +- to identify the core. +-- reg: +- should contain the configuration address space. +-- reg-names: Must be +- - "elbi" External local bus interface registers +- - "cfg" Meson specific registers +- - "config" PCIe configuration space +-- reset-gpios: The GPIO to generate PCIe PERST# assert and deassert signal. +-- clocks: Must contain an entry for each entry in clock-names. +-- clock-names: Must include the following entries: +- - "pclk" PCIe GEN 100M PLL clock +- - "port" PCIe_x(A or B) RC clock gate +- - "general" PCIe Phy clock +-- resets: phandle to the reset lines. +-- reset-names: must contain "port" and "apb" +- - "port" Port A or B reset +- - "apb" Share APB reset +-- phys: should contain a phandle to the PCIE phy +-- phy-names: must contain "pcie" +- +-- device_type: +- should be "pci". As specified in snps,dw-pcie.yaml +- +- +-Example configuration: +- +- pcie: pcie@f9800000 { +- compatible = "amlogic,axg-pcie", "snps,dw-pcie"; +- reg = <0x0 0xf9800000 0x0 0x400000 +- 0x0 0xff646000 0x0 0x2000 +- 0x0 0xf9f00000 0x0 0x100000>; +- reg-names = "elbi", "cfg", "config"; +- reset-gpios = <&gpio GPIOX_19 GPIO_ACTIVE_HIGH>; +- interrupts = ; +- #interrupt-cells = <1>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic GIC_SPI 179 IRQ_TYPE_EDGE_RISING>; +- bus-range = <0x0 0xff>; +- #address-cells = <3>; +- #size-cells = <2>; +- device_type = "pci"; +- ranges = <0x82000000 0 0 0x0 0xf9c00000 0 0x00300000>; +- +- clocks = <&clkc CLKID_USB +- &clkc CLKID_PCIE_A +- &clkc CLKID_PCIE_CML_EN0>; +- clock-names = "general", +- "pclk", +- "port"; +- resets = <&reset RESET_PCIE_A>, +- <&reset RESET_PCIE_APB>; +- reset-names = "port", +- "apb"; +- phys = <&pcie_phy>; +- phy-names = "pcie"; +- }; +-- +2.51.0 + diff --git a/queue-6.1/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch b/queue-6.1/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch new file mode 100644 index 0000000000..1d1278b2eb --- /dev/null +++ b/queue-6.1/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch @@ -0,0 +1,71 @@ +From fe6da7001dc9d2d347c36faffe694f89b4057ca9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:23 +0000 +Subject: efi/libstub: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit 84361123413efc84b06f3441c6c827b95d902732 ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags Bits above the + physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The pgd value is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c +index 479dd445acdcf..267b1c5312540 100644 +--- a/drivers/firmware/efi/libstub/x86-5lvl.c ++++ b/drivers/firmware/efi/libstub/x86-5lvl.c +@@ -66,7 +66,7 @@ void efi_5level_switch(void) + bool have_la57 = native_read_cr4() & X86_CR4_LA57; + bool need_toggle = want_la57 ^ have_la57; + u64 *pgt = (void *)la57_toggle + PAGE_SIZE; +- u64 *cr3 = (u64 *)__native_read_cr3(); ++ pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); + u64 *new_cr3; + + if (!la57_toggle || !need_toggle) +@@ -82,7 +82,7 @@ void efi_5level_switch(void) + new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; + } else { + /* take the new root table pointer from the current entry #0 */ +- new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); ++ new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); + + /* copy the new root table if it is not 32-bit addressable */ + if ((u64)new_cr3 > U32_MAX) +-- +2.51.0 + diff --git a/queue-6.1/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-6.1/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..2153cb6752 --- /dev/null +++ b/queue-6.1/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From 6b72396562a771e0348aca283dc7b4d1d900ef3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index e8ec213b21443..e01632462db9f 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -481,7 +481,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-6.1/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-6.1/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..8a7f95a605 --- /dev/null +++ b/queue-6.1/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From 9a52a35efac3d1681f0af24bcfc7dc96dd286689 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index db302f617da72..8282fbc1a6892 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -666,6 +666,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -707,15 +725,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -731,15 +740,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-6.1/ext4-remove-unused-return-value-of-__mb_check_buddy.patch b/queue-6.1/ext4-remove-unused-return-value-of-__mb_check_buddy.patch new file mode 100644 index 0000000000..82788c4a06 --- /dev/null +++ b/queue-6.1/ext4-remove-unused-return-value-of-__mb_check_buddy.patch @@ -0,0 +1,63 @@ +From e0ab39007947c33b3c8cfdc6b4f45deacd01e1b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Jan 2024 17:20:54 +0800 +Subject: ext4: remove unused return value of __mb_check_buddy + +From: Kemeng Shi + +[ Upstream commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 ] + +Remove unused return value of __mb_check_buddy. + +Signed-off-by: Kemeng Shi +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240105092102.496631-2-shikemeng@huaweicloud.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation") +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 1dc25e7b922ad..db302f617da72 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -666,7 +666,7 @@ do { \ + } \ + } while (0) + +-static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, ++static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { + struct super_block *sb = e4b->bd_sb; +@@ -685,7 +685,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + void *buddy2; + + if (e4b->bd_info->bb_check_counter++ % 10) +- return 0; ++ return; + + while (order > 1) { + buddy = mb_find_buddy(e4b, order, &max); +@@ -747,7 +747,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + + grp = ext4_get_group_info(sb, e4b->bd_group); + if (!grp) +- return NULL; ++ return; + list_for_each(cur, &grp->bb_prealloc_list) { + ext4_group_t groupnr; + struct ext4_prealloc_space *pa; +@@ -757,7 +757,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + for (i = 0; i < pa->pa_len; i++) + MB_CHECK_ASSERT(mb_test_bit(k + i, buddy)); + } +- return 0; + } + #undef MB_CHECK_ASSERT + #define mb_check_buddy(e4b) __mb_check_buddy(e4b, \ +-- +2.51.0 + diff --git a/queue-6.1/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-6.1/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..d652f9da50 --- /dev/null +++ b/queue-6.1/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From 7a2f60b5e0c089a93a6ba0c0d6fbbd62599b80f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index 5c891aa00d596..b9fefa844574e 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -732,7 +732,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -812,6 +812,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-6.1/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-6.1/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..89172537f1 --- /dev/null +++ b/queue-6.1/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From 5d8712e92b59f2a090a22ae3fdcf5b84ba5400e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index d9dcc20945c6a..32b1ca4e10508 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -160,8 +160,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-6.1/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch b/queue-6.1/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch new file mode 100644 index 0000000000..f854160687 --- /dev/null +++ b/queue-6.1/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch @@ -0,0 +1,40 @@ +From ef1338e5a897b39e82b3725ecdb365346452537e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:58:13 -0600 +Subject: firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc + +From: Dinh Nguyen + +[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ] + +Fix this warning that was generated from "make htmldocs": + +WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' +not described in 'stratix10_svc' + +Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ +Signed-off-by: Dinh Nguyen +Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/stratix10-svc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index bb4adfc30218d..80898fc68bc31 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -51,6 +51,7 @@ struct stratix10_svc_chan; + /** + * struct stratix10_svc - svc private data + * @stratix10_svc_rsu: pointer to stratix10 RSU device ++ * @intel_svc_fcs: pointer to the FCS device + */ + struct stratix10_svc { + struct platform_device *stratix10_svc_rsu; +-- +2.51.0 + diff --git a/queue-6.1/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-6.1/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..8ae0bd8dcb --- /dev/null +++ b/queue-6.1/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From 9cafdd24f93be949b0cd72ce77df5dc7e8481d4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index fb572688f919f..f1f5b84e2ef17 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1067,9 +1067,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-6.1/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-6.1/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..17b486108f --- /dev/null +++ b/queue-6.1/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From bfe537bb1c28453e0e4b0cb9a627aba639728bb0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index f1f5b84e2ef17..1ac0a7b87c651 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -377,8 +377,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.1/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-6.1/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..37d9d0346c --- /dev/null +++ b/queue-6.1/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 493b1c84cdeda5f9a136bc55946bcf11a29ad50e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index f87a8705f5183..51a1d2f95621b 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -393,8 +393,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -417,7 +415,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-6.1/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch b/queue-6.1/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch new file mode 100644 index 0000000000..0876d84ee6 --- /dev/null +++ b/queue-6.1/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch @@ -0,0 +1,54 @@ +From a3e0263d5dad6841deadd48ab180f8d51bfdd2b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 00:26:02 +0800 +Subject: hwmon: sy7636a: Fix regulator_enable resource leak on error path + +From: Haotian Zhang + +[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ] + +In sy7636a_sensor_probe(), regulator_enable() is called but if +devm_hwmon_device_register_with_info() fails, the function returns +without calling regulator_disable(), leaving the regulator enabled +and leaking the reference count. + +Switch to devm_regulator_get_enable() to automatically +manage the regulator resource. + +Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sy7636a-hwmon.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c +index 9fabd60e9a970..73d958de485d8 100644 +--- a/drivers/hwmon/sy7636a-hwmon.c ++++ b/drivers/hwmon/sy7636a-hwmon.c +@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { + static int sy7636a_sensor_probe(struct platform_device *pdev) + { + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); +- struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + +- regulator = devm_regulator_get(&pdev->dev, "vcom"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); ++ err = devm_regulator_get_enable(&pdev->dev, "vcom"); + if (err) + return err; + +-- +2.51.0 + diff --git a/queue-6.1/i3c-allow-of-alias-based-persistent-bus-numbering.patch b/queue-6.1/i3c-allow-of-alias-based-persistent-bus-numbering.patch new file mode 100644 index 0000000000..eb63bb3dc8 --- /dev/null +++ b/queue-6.1/i3c-allow-of-alias-based-persistent-bus-numbering.patch @@ -0,0 +1,121 @@ +From 4a02a6bd6fe64dd6ae8ea441cb0bcc6a1c74806d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Apr 2023 17:41:49 +0800 +Subject: i3c: Allow OF-alias-based persistent bus numbering + +From: Jeremy Kerr + +[ Upstream commit 7dc2e0a875645a79f5c1c063019397e8e94008f5 ] + +Parse the /aliases node to assign any fixed bus numbers, as is done with +the i2c subsystem. Numbering for non-aliased busses will start after the +highest fixed bus number. + +This allows an alias node such as: + + aliases { + i3c0 = &bus_a, + i3c4 = &bus_b, + }; + +to set the numbering for a set of i3c controllers: + + /* fixed-numbered bus, assigned "i3c-0" */ + bus_a: i3c-master { + }; + + /* another fixed-numbered bus, assigned "i3c-4" */ + bus_b: i3c-master { + }; + + /* dynamic-numbered bus, likely assigned "i3c-5" */ + bus_c: i3c-master { + }; + +If no i3c device aliases are present, the numbering will stay as-is, +starting from 0. + +Signed-off-by: Jeremy Kerr +Link: https://lore.kernel.org/r/20230405094149.1513209-1-jk@codeconstruct.com.au +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 30 +++++++++++++++++++++++++----- + 1 file changed, 25 insertions(+), 5 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 019fd9bd928d0..2f5cef08e737e 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -21,6 +21,7 @@ + + static DEFINE_IDR(i3c_bus_idr); + static DEFINE_MUTEX(i3c_core_lock); ++static int __i3c_first_dynamic_bus_num; + + /** + * i3c_bus_maintenance_lock - Lock the bus for a maintenance operation +@@ -462,9 +463,9 @@ static void i3c_bus_cleanup(struct i3c_bus *i3cbus) + mutex_unlock(&i3c_core_lock); + } + +-static int i3c_bus_init(struct i3c_bus *i3cbus) ++static int i3c_bus_init(struct i3c_bus *i3cbus, struct device_node *np) + { +- int ret; ++ int ret, start, end, id = -1; + + init_rwsem(&i3cbus->lock); + INIT_LIST_HEAD(&i3cbus->devs.i2c); +@@ -472,8 +473,19 @@ static int i3c_bus_init(struct i3c_bus *i3cbus) + i3c_bus_init_addrslots(i3cbus); + i3cbus->mode = I3C_BUS_MODE_PURE; + ++ if (np) ++ id = of_alias_get_id(np, "i3c"); ++ + mutex_lock(&i3c_core_lock); +- ret = idr_alloc(&i3c_bus_idr, i3cbus, 0, 0, GFP_KERNEL); ++ if (id >= 0) { ++ start = id; ++ end = start + 1; ++ } else { ++ start = __i3c_first_dynamic_bus_num; ++ end = 0; ++ } ++ ++ ret = idr_alloc(&i3c_bus_idr, i3cbus, start, end, GFP_KERNEL); + mutex_unlock(&i3c_core_lock); + + if (ret < 0) +@@ -2751,7 +2763,7 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus); ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); + if (ret) + return ret; + +@@ -2956,8 +2968,16 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) + + static int __init i3c_init(void) + { +- int res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); ++ int res; ++ ++ res = of_alias_get_highest_id("i3c"); ++ if (res >= 0) { ++ mutex_lock(&i3c_core_lock); ++ __i3c_first_dynamic_bus_num = res + 1; ++ mutex_unlock(&i3c_core_lock); ++ } + ++ res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier); + if (res) + return res; + +-- +2.51.0 + diff --git a/queue-6.1/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-6.1/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..2c674b3935 --- /dev/null +++ b/queue-6.1/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From b2a799f5aec0561fee6d1be0cd34f19701d20949 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 60a61e39e2bb7..44574474bda35 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2763,10 +2763,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2774,6 +2770,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.1/i3c-master-inherit-dma-masks-and-parameters-from-par.patch b/queue-6.1/i3c-master-inherit-dma-masks-and-parameters-from-par.patch new file mode 100644 index 0000000000..64b6185fa1 --- /dev/null +++ b/queue-6.1/i3c-master-inherit-dma-masks-and-parameters-from-par.patch @@ -0,0 +1,40 @@ +From ea0f6d8874394ddd74a0f308f95e07cd82aa81d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:53 +0300 +Subject: i3c: master: Inherit DMA masks and parameters from parent device + +From: Jarkko Nikula + +[ Upstream commit 0c35691551387e060e6ae7a6652b4101270c73cf ] + +Copy the DMA masks and parameters for an I3C master device from parent +device so that the master device has them set for the DMA buffer and +mapping API. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-2-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 2f5cef08e737e..60a61e39e2bb7 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2770,6 +2770,10 @@ int i3c_master_register(struct i3c_master_controller *master, + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + ++ master->dev.dma_mask = parent->dma_mask; ++ master->dev.coherent_dma_mask = parent->coherent_dma_mask; ++ master->dev.dma_parms = parent->dma_parms; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.1/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-6.1/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..7ec8d2da7e --- /dev/null +++ b/queue-6.1/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From a6188cbe73c1a734c3f29a755fcdf082f6f27421 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index fda472d84549b..21ea4166057d8 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -350,21 +350,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-6.1/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-6.1/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..ce94563bc3 --- /dev/null +++ b/queue-6.1/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From b32cf1f863dad6a29f89c5b2cdfa623a04448d17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 1f930711db769..3eba0d27bc125 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -646,7 +646,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-6.1/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-6.1/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..1385b5d5c2 --- /dev/null +++ b/queue-6.1/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From a4934dc893b6b3adfb52597c05bab53c96af1866 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 2da169ea7cc18..2d34dd5941e79 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -821,6 +821,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 5e7cdcebd64f8..24e4bec52bb2f 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -663,8 +663,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -673,6 +676,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-6.1/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch b/queue-6.1/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch new file mode 100644 index 0000000000..7187d3799d --- /dev/null +++ b/queue-6.1/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch @@ -0,0 +1,38 @@ +From b17a240a338cac7af522bfc055b270194f50abaa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:00 +0300 +Subject: interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS + +From: Dmitry Baryshkov + +[ Upstream commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 ] + +>From the initial submission the interconnect driver missed the link from +SNOC_PNOC to the USB 2 configuration space. Add missing link in order to +let the platform configure and utilize this path. + +Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/msm8996.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c +index 14efd2761b7ab..680d7e56d6a7f 100644 +--- a/drivers/interconnect/qcom/msm8996.c ++++ b/drivers/interconnect/qcom/msm8996.c +@@ -557,6 +557,7 @@ static struct qcom_icc_node mas_venus_vmem = { + static const u16 mas_snoc_pnoc_links[] = { + MSM8996_SLAVE_BLSP_1, + MSM8996_SLAVE_BLSP_2, ++ MSM8996_SLAVE_USB_HS, + MSM8996_SLAVE_SDCC_1, + MSM8996_SLAVE_SDCC_2, + MSM8996_SLAVE_SDCC_4, +-- +2.51.0 + diff --git a/queue-6.1/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-6.1/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..ffd3978da4 --- /dev/null +++ b/queue-6.1/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From 8d7bb9fc675d00643742df19ec1083fe80cc3a3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 3d1313ed7a84f..fe25faba39aa3 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -282,17 +282,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -315,6 +317,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-6.1/irqchip-imx-mu-msi-fix-section-mismatch.patch b/queue-6.1/irqchip-imx-mu-msi-fix-section-mismatch.patch new file mode 100644 index 0000000000..ccaf12d52f --- /dev/null +++ b/queue-6.1/irqchip-imx-mu-msi-fix-section-mismatch.patch @@ -0,0 +1,63 @@ +From b81e1cd0f967e405de7936665b9b0692ce6ca9a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:06 +0200 +Subject: irqchip/imx-mu-msi: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 64acfd8e680ff8992c101fe19aadb112ce551072 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index 229039eda1b1f..9b158d0043fb4 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -303,9 +303,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int __init imx_mu_of_init(struct device_node *dn, +- struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { + struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; +@@ -423,20 +422,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + } + +-static int __init imx_mu_imx6sx_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + } + +-static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + } +-- +2.51.0 + diff --git a/queue-6.1/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch b/queue-6.1/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch new file mode 100644 index 0000000000..4825d9972f --- /dev/null +++ b/queue-6.1/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch @@ -0,0 +1,50 @@ +From 50384c01d3da6d9bfe94c1ab2542e2736aebc414 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:03 +0200 +Subject: irqchip/irq-bcm7038-l1: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index a62b96237b826..187f535794461 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -220,9 +220,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, + } + #endif + +-static int __init bcm7038_l1_init_one(struct device_node *dn, +- unsigned int idx, +- struct bcm7038_l1_chip *intc) ++static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, ++ struct bcm7038_l1_chip *intc) + { + struct resource res; + resource_size_t sz; +@@ -396,8 +395,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int __init bcm7038_l1_of_init(struct device_node *dn, +- struct device_node *parent) ++static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) + { + struct bcm7038_l1_chip *intc; + int idx, ret; +-- +2.51.0 + diff --git a/queue-6.1/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch b/queue-6.1/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..49ed615ee7 --- /dev/null +++ b/queue-6.1/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch @@ -0,0 +1,79 @@ +From 610e11748a686c50adf94e3a702bac6508c9c693 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:04 +0200 +Subject: irqchip/irq-bcm7120-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bfc0c5beab1fde843677923cf008f41d583c980a ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index 1e9dab6e0d86f..bb6e56629e532 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -147,8 +147,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + int ret; + +@@ -181,8 +180,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + unsigned int gc_idx; + +@@ -212,10 +210,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_probe(struct device_node *dn, +- struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, +- struct bcm7120_l2_intc_data *), ++ struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; +@@ -343,15 +340,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, + return ret; + } + +-static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); +-- +2.51.0 + diff --git a/queue-6.1/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch b/queue-6.1/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..4b5048f542 --- /dev/null +++ b/queue-6.1/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch @@ -0,0 +1,58 @@ +From ef26b7dd04842d22c70e1b0853780d5823f291de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:05 +0200 +Subject: irqchip/irq-brcmstb-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bbe1775924478e95372c2f896064ab6446000713 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index 5d4421f75b43a..f1e244e1ba3bb 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -158,10 +158,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_gc_unlock_irqrestore(gc, flags); + } + +-static int __init brcmstb_l2_intc_of_init(struct device_node *np, +- struct device_node *parent, +- const struct brcmstb_intc_init_params +- *init_params) ++static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; +@@ -277,14 +275,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, + return ret; + } + +-static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + } + +-static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + } +-- +2.51.0 + diff --git a/queue-6.1/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-6.1/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..5aa9f20a00 --- /dev/null +++ b/queue-6.1/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From d3740d6858edb9275e06386e7868f536982361a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-6.1/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-6.1/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..2f5a032a1a --- /dev/null +++ b/queue-6.1/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From f9ba4c8cca21e991b362be0e95270a450985a59d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index 6692de0af68f1..ea0801b9cb010 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-6.1/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-6.1/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..4bb09aab77 --- /dev/null +++ b/queue-6.1/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From cf6e9884123abd04e5efb033ead37c4f5647bcb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index 2b0b5f08b8fc0..f039d5cae3756 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1862,9 +1862,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1930,6 +1927,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-6.1/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-6.1/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..fca27eff4a --- /dev/null +++ b/queue-6.1/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From 6a2661931f661f54fdb4606832066672575d3bb4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index d8c4d5664145d..44e332ee99d38 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -186,13 +186,14 @@ static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-6.1/md-export-md_is_rdwr-and-is_md_suspended.patch b/queue-6.1/md-export-md_is_rdwr-and-is_md_suspended.patch new file mode 100644 index 0000000000..24b04967fc --- /dev/null +++ b/queue-6.1/md-export-md_is_rdwr-and-is_md_suspended.patch @@ -0,0 +1,87 @@ +From c07aee512e62ca148f1e0abaa547229ed62abd94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 May 2023 09:56:08 +0800 +Subject: md: export md_is_rdwr() and is_md_suspended() + +From: Yu Kuai + +[ Upstream commit 431e61257d631157e1d374f1368febf37aa59f7c ] + +The two apis will be used later to fix a deadlock in raid456, there are +no functional changes. + +Signed-off-by: Yu Kuai +Signed-off-by: Song Liu +Link: https://lore.kernel.org/r/20230512015610.821290-4-yukuai1@huaweicloud.com +Stable-dep-of: a913d1f6a7f6 ("md/raid5: fix IO hang when array is broken with IO inflight") +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 16 ---------------- + drivers/md/md.h | 17 +++++++++++++++++ + 2 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index a9fcfcbc2d110..fa1f487eb0300 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -93,18 +93,6 @@ static int remove_and_add_spares(struct mddev *mddev, + struct md_rdev *this); + static void mddev_detach(struct mddev *mddev); + +-enum md_ro_state { +- MD_RDWR, +- MD_RDONLY, +- MD_AUTO_READ, +- MD_MAX_STATE +-}; +- +-static bool md_is_rdwr(struct mddev *mddev) +-{ +- return (mddev->ro == MD_RDWR); +-} +- + /* + * Default number of read corrections we'll attempt on an rdev + * before ejecting it from the array. We divide the read error +@@ -380,10 +368,6 @@ EXPORT_SYMBOL_GPL(md_new_event); + static LIST_HEAD(all_mddevs); + static DEFINE_SPINLOCK(all_mddevs_lock); + +-static bool is_md_suspended(struct mddev *mddev) +-{ +- return percpu_ref_is_dying(&mddev->active_io); +-} + /* Rather than calling directly into the personality make_request function, + * IO requests come here first so that we can check if the device is + * being suspended pending a reconfiguration. +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 1fda5e139beb0..1d048976e7432 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -555,6 +555,23 @@ enum recovery_flags { + MD_RESYNCING_REMOTE, /* remote node is running resync thread */ + }; + ++enum md_ro_state { ++ MD_RDWR, ++ MD_RDONLY, ++ MD_AUTO_READ, ++ MD_MAX_STATE ++}; ++ ++static inline bool md_is_rdwr(struct mddev *mddev) ++{ ++ return (mddev->ro == MD_RDWR); ++} ++ ++static inline bool is_md_suspended(struct mddev *mddev) ++{ ++ return percpu_ref_is_dying(&mddev->active_io); ++} ++ + static inline int __must_check mddev_lock(struct mddev *mddev) + { + return mutex_lock_interruptible(&mddev->reconfig_mutex); +-- +2.51.0 + diff --git a/queue-6.1/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch b/queue-6.1/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch new file mode 100644 index 0000000000..3422ba45d3 --- /dev/null +++ b/queue-6.1/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch @@ -0,0 +1,99 @@ +From 76a638dd549299a6d35a2220b9d1babeb3fe8e9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 16:55:57 +0800 +Subject: md/raid5: fix IO hang when array is broken with IO inflight + +From: Yu Kuai + +[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ] + +Following test can cause IO hang: + +mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none +sleep 5 +echo 1 > /sys/block/sda/device/delete +echo 1 > /sys/block/sdb/device/delete +echo 1 > /sys/block/sdc/device/delete +echo 1 > /sys/block/sdd/device/delete + +dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct + +Root cause: + +1) all disks removed, however all rdevs in the array is still in sync, +IO will be issued normally. + +2) IO failure from sda, and set badblocks failed, sda will be faulty +and MD_SB_CHANGING_PENDING will be set. + +3) error recovery try to recover this IO from other disks, IO will be +issued to sdb, sdc, and sdd. + +4) IO failure from sdb, and set badblocks failed again, now array is +broken and will become read-only. + +5) IO failure from sdc and sdd, however, stripe can't be handled anymore +because MD_SB_CHANGING_PENDING is set: + +handle_stripe + handle_stripe + if (test_bit MD_SB_CHANGING_PENDING) + set_bit STRIPE_HANDLE + goto finish + // skip handling failed stripe + +release_stripe + if (test_bit STRIPE_HANDLE) + list_add_tail conf->hand_list + +6) later raid5d can't handle failed stripe as well: + +raid5d + md_check_recovery + md_update_sb + if (!md_is_rdwr()) + // can't clear pending bit + return + if (test_bit MD_SB_CHANGING_PENDING) + break; + // can't handle failed stripe + +Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, +fix this problem by skip this checking for read-only array. + +Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com +Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") +Signed-off-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 6e80a439ec456..bce6d0d10a7cd 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -5044,7 +5044,8 @@ static void handle_stripe(struct stripe_head *sh) + goto finish; + + if (s.handle_bad_blocks || +- test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { ++ (md_is_rdwr(conf->mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { + set_bit(STRIPE_HANDLE, &sh->state); + goto finish; + } +@@ -6802,7 +6803,8 @@ static void raid5d(struct md_thread *thread) + int batch_size, released; + unsigned int offset; + +- if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ if (md_is_rdwr(mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + + released = release_stripe_list(conf, conf->temp_inactive_list); +-- +2.51.0 + diff --git a/queue-6.1/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-6.1/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..ce46396a9c --- /dev/null +++ b/queue-6.1/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From 80fbf6e4067199d2ac47199ada64bfc85b344ad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index c3bcbd8905c6c..a520890090ba4 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.1/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.1/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..4724dea119 --- /dev/null +++ b/queue-6.1/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 55d51c0b0db3f7fd5b8daaca5fde15831883e7bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index 389756436af6c..d1e6e473c8e0a 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -287,6 +287,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.1/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.1/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..791936b03a --- /dev/null +++ b/queue-6.1/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 67e9a53647cd23223704f7d27360b7a493534854 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index eff53fed8fe73..eee40ec162ceb 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -213,6 +213,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.1/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-6.1/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..a93c864403 --- /dev/null +++ b/queue-6.1/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From 70067eb0d0d2f91af2ccb4d501371c51fd768700 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 3dac76e6df4d2..53f6766938ae2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -869,8 +869,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-6.1/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-6.1/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..26b4b919de --- /dev/null +++ b/queue-6.1/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From 68451592e5dbe92e7c731c9f90c9d6a921861d6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index ee063baed136c..5c39c9c653233 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -562,7 +562,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -578,7 +578,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -604,7 +604,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-6.1/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch b/queue-6.1/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch new file mode 100644 index 0000000000..60f557507d --- /dev/null +++ b/queue-6.1/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch @@ -0,0 +1,45 @@ +From 9e440cfa58279da0a07b6e869246f565a40da298 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 00:35:51 +0800 +Subject: mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors + +From: Haotian Zhang + +[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ] + +devm_pm_runtime_enable() can fail due to memory allocation failures. +The current code ignores its return value and proceeds with +pm_runtime_resume_and_get(), which may operate on incorrectly +initialized runtime PM state. + +Check the return value of devm_pm_runtime_enable() and return the +error code if it fails. + +Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c +index 3b6b0ada597ac..d57fd44e830d3 100644 +--- a/drivers/mtd/nand/raw/renesas-nand-controller.c ++++ b/drivers/mtd/nand/raw/renesas-nand-controller.c +@@ -1342,7 +1342,10 @@ static int rnandc_probe(struct platform_device *pdev) + if (IS_ERR(rnandc->regs)) + return PTR_ERR(rnandc->regs); + +- devm_pm_runtime_enable(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +-- +2.51.0 + diff --git a/queue-6.1/nbd-defer-config-put-in-recv_work.patch b/queue-6.1/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..39e66c8306 --- /dev/null +++ b/queue-6.1/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From 35f03c81e16e73e56f7e3a5f06f09fe63ce1c0d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 2a959c08bd3cb..80a2d346a51cc 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -889,9 +889,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-6.1/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-6.1/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..971cfb9710 --- /dev/null +++ b/queue-6.1/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From 126e4d5effb5e386ec71c2a3dcfe5a376097c370 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 80a2d346a51cc..008534aad0a18 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2116,12 +2116,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-6.1/net-phy-adin1100-fix-software-power-down-ready-condi.patch b/queue-6.1/net-phy-adin1100-fix-software-power-down-ready-condi.patch new file mode 100644 index 0000000000..39a16533a2 --- /dev/null +++ b/queue-6.1/net-phy-adin1100-fix-software-power-down-ready-condi.patch @@ -0,0 +1,54 @@ +From dd9862c1da45c10e73a1081984cb9a0e0592b884 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:47:36 +0100 +Subject: net: phy: adin1100: Fix software power-down ready condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ] + +Value CRSM_SFT_PD written to Software Power-Down Control Register +(CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value +CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for +confirmation powerdown has been reached. + +The condition could have only worked when disabling powerdown +(both 0x00), but never when enabling it (0x01 != 0x02). + +Result is a timeout, like so: + + $ ifdown eth0 + macb f802c000.ethernet eth0: Link is Down + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + +Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") +Signed-off-by: Alexander Dahl +Reviewed-by: Russell King (Oracle) +Acked-by: Nuno Sá +Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/adin1100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c +index 7619d6185801c..2f47b7020e12b 100644 +--- a/drivers/net/phy/adin1100.c ++++ b/drivers/net/phy/adin1100.c +@@ -148,7 +148,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) + return ret; + + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, +- (ret & ADIN_CRSM_SFT_PD_RDY) == val, ++ !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, + 1000, 30000, true); + } + +-- +2.51.0 + diff --git a/queue-6.1/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-6.1/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..cfc5ccf137 --- /dev/null +++ b/queue-6.1/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From 6cf989c7e30a467c84aca6442992089395c0d102 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index d99e1603c32a6..e4fd66a1c5cd4 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1608,7 +1608,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1754,14 +1753,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1834,6 +1833,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1844,13 +1845,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1859,11 +1860,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1938,24 +1939,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-6.1/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-6.1/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..123bfb0d3c --- /dev/null +++ b/queue-6.1/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From 8c1a0ef4fdd85f451305fb7d27085ec645e441bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 03fbb611b2a67..202c43d73a2bd 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5065,10 +5065,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-6.1/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-6.1/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..6e418e0d80 --- /dev/null +++ b/queue-6.1/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From 4c349d078f6b8a8f44e2ee08fe737048694b14df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 9d335aa58907d..786519740b559 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -140,12 +140,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-6.1/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-6.1/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..1e9caaee65 --- /dev/null +++ b/queue-6.1/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,503 @@ +From 59aac0dd781ba36ef48e421c45f2a118070ce633 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index e227d997fc716..115bb7e572f7d 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family + void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 6156c0751056c..7a8a6f72ff198 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if ((u32)jiffies == list->last_gc) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen) +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 793994622b87d..0edde415f6fc5 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index d1d0fa6c8061e..b3e4be6e1e436 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 2302bae1e0128..b6ec5497b930f 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -1166,8 +1166,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -1180,8 +1180,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -1210,8 +1211,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -2066,8 +2066,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-6.1/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-6.1/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..89d4c57d56 --- /dev/null +++ b/queue-6.1/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From 44a8400c09003182b1af22722f35713974aac787 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 7a8a6f72ff198..97b631a81484d 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if ((u32)jiffies == list->last_gc) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 0edde415f6fc5..f47a4932dc734 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-6.1/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-6.1/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..f6d7471519 --- /dev/null +++ b/queue-6.1/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 49a892a04f60087d73d3427ba499ce0854ef499d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index 59f119cce3dc6..3a9415fd77546 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -53,7 +54,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-6.1/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-6.1/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..c1725c4fb1 --- /dev/null +++ b/queue-6.1/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From da4ece264322314da58c6b630d518e4bb7a02c4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index accff95baa847..785aa1673359a 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1700,6 +1700,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-6.1/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-6.1/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..6fb06439fe --- /dev/null +++ b/queue-6.1/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From 80e10ebe7fa619a45a459a3e1550cef25bfaebdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index a7e2009419c37..8c165b791a1c8 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1338,7 +1338,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-6.1/ntfs3-init-run-lock-for-extend-inode.patch b/queue-6.1/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..963485cf81 --- /dev/null +++ b/queue-6.1/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From 6ad52229102149672f6221995f9f65066c15921e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 785aa1673359a..e47eec61f2379 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -457,6 +457,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-6.1/objtool-fix-find_-symbol-func-_containing.patch b/queue-6.1/objtool-fix-find_-symbol-func-_containing.patch new file mode 100644 index 0000000000..99d0bf6fc4 --- /dev/null +++ b/queue-6.1/objtool-fix-find_-symbol-func-_containing.patch @@ -0,0 +1,423 @@ +From 5f9c993aa316b656a99e70c29ae019471eb21820 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 Sep 2022 13:11:12 +0200 +Subject: objtool: Fix find_{symbol,func}_containing() + +From: Peter Zijlstra + +[ Upstream commit 5da6aea375cde499fdfac3cde4f26df4a840eb9f ] + +The current find_{symbol,func}_containing() functions are broken in +the face of overlapping symbols, exactly the case that is needed for a +new ibt/endbr supression. + +Import interval_tree_generic.h into the tools tree and convert the +symbol tree to an interval tree to support proper range stabs. + +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Thomas Gleixner +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20220915111146.330203761@infradead.org +Stable-dep-of: 72567c630d32 ("objtool: Fix weak symbol detection") +Signed-off-by: Sasha Levin +--- + tools/include/linux/interval_tree_generic.h | 187 ++++++++++++++++++++ + tools/objtool/elf.c | 93 +++++----- + tools/objtool/include/objtool/elf.h | 3 +- + 3 files changed, 229 insertions(+), 54 deletions(-) + create mode 100644 tools/include/linux/interval_tree_generic.h + +diff --git a/tools/include/linux/interval_tree_generic.h b/tools/include/linux/interval_tree_generic.h +new file mode 100644 +index 0000000000000..aaa8a0767aa3a +--- /dev/null ++++ b/tools/include/linux/interval_tree_generic.h +@@ -0,0 +1,187 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* ++ Interval Trees ++ (C) 2012 Michel Lespinasse ++ ++ ++ include/linux/interval_tree_generic.h ++*/ ++ ++#include ++ ++/* ++ * Template for implementing interval trees ++ * ++ * ITSTRUCT: struct type of the interval tree nodes ++ * ITRB: name of struct rb_node field within ITSTRUCT ++ * ITTYPE: type of the interval endpoints ++ * ITSUBTREE: name of ITTYPE field within ITSTRUCT holding last-in-subtree ++ * ITSTART(n): start endpoint of ITSTRUCT node n ++ * ITLAST(n): last endpoint of ITSTRUCT node n ++ * ITSTATIC: 'static' or empty ++ * ITPREFIX: prefix to use for the inline tree definitions ++ * ++ * Note - before using this, please consider if generic version ++ * (interval_tree.h) would work for you... ++ */ ++ ++#define INTERVAL_TREE_DEFINE(ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, \ ++ ITSTART, ITLAST, ITSTATIC, ITPREFIX) \ ++ \ ++/* Callbacks for augmented rbtree insert and remove */ \ ++ \ ++RB_DECLARE_CALLBACKS_MAX(static, ITPREFIX ## _augment, \ ++ ITSTRUCT, ITRB, ITTYPE, ITSUBTREE, ITLAST) \ ++ \ ++/* Insert / remove interval nodes from the tree */ \ ++ \ ++ITSTATIC void ITPREFIX ## _insert(ITSTRUCT *node, \ ++ struct rb_root_cached *root) \ ++{ \ ++ struct rb_node **link = &root->rb_root.rb_node, *rb_parent = NULL; \ ++ ITTYPE start = ITSTART(node), last = ITLAST(node); \ ++ ITSTRUCT *parent; \ ++ bool leftmost = true; \ ++ \ ++ while (*link) { \ ++ rb_parent = *link; \ ++ parent = rb_entry(rb_parent, ITSTRUCT, ITRB); \ ++ if (parent->ITSUBTREE < last) \ ++ parent->ITSUBTREE = last; \ ++ if (start < ITSTART(parent)) \ ++ link = &parent->ITRB.rb_left; \ ++ else { \ ++ link = &parent->ITRB.rb_right; \ ++ leftmost = false; \ ++ } \ ++ } \ ++ \ ++ node->ITSUBTREE = last; \ ++ rb_link_node(&node->ITRB, rb_parent, link); \ ++ rb_insert_augmented_cached(&node->ITRB, root, \ ++ leftmost, &ITPREFIX ## _augment); \ ++} \ ++ \ ++ITSTATIC void ITPREFIX ## _remove(ITSTRUCT *node, \ ++ struct rb_root_cached *root) \ ++{ \ ++ rb_erase_augmented_cached(&node->ITRB, root, &ITPREFIX ## _augment); \ ++} \ ++ \ ++/* \ ++ * Iterate over intervals intersecting [start;last] \ ++ * \ ++ * Note that a node's interval intersects [start;last] iff: \ ++ * Cond1: ITSTART(node) <= last \ ++ * and \ ++ * Cond2: start <= ITLAST(node) \ ++ */ \ ++ \ ++static ITSTRUCT * \ ++ITPREFIX ## _subtree_search(ITSTRUCT *node, ITTYPE start, ITTYPE last) \ ++{ \ ++ while (true) { \ ++ /* \ ++ * Loop invariant: start <= node->ITSUBTREE \ ++ * (Cond2 is satisfied by one of the subtree nodes) \ ++ */ \ ++ if (node->ITRB.rb_left) { \ ++ ITSTRUCT *left = rb_entry(node->ITRB.rb_left, \ ++ ITSTRUCT, ITRB); \ ++ if (start <= left->ITSUBTREE) { \ ++ /* \ ++ * Some nodes in left subtree satisfy Cond2. \ ++ * Iterate to find the leftmost such node N. \ ++ * If it also satisfies Cond1, that's the \ ++ * match we are looking for. Otherwise, there \ ++ * is no matching interval as nodes to the \ ++ * right of N can't satisfy Cond1 either. \ ++ */ \ ++ node = left; \ ++ continue; \ ++ } \ ++ } \ ++ if (ITSTART(node) <= last) { /* Cond1 */ \ ++ if (start <= ITLAST(node)) /* Cond2 */ \ ++ return node; /* node is leftmost match */ \ ++ if (node->ITRB.rb_right) { \ ++ node = rb_entry(node->ITRB.rb_right, \ ++ ITSTRUCT, ITRB); \ ++ if (start <= node->ITSUBTREE) \ ++ continue; \ ++ } \ ++ } \ ++ return NULL; /* No match */ \ ++ } \ ++} \ ++ \ ++ITSTATIC ITSTRUCT * \ ++ITPREFIX ## _iter_first(struct rb_root_cached *root, \ ++ ITTYPE start, ITTYPE last) \ ++{ \ ++ ITSTRUCT *node, *leftmost; \ ++ \ ++ if (!root->rb_root.rb_node) \ ++ return NULL; \ ++ \ ++ /* \ ++ * Fastpath range intersection/overlap between A: [a0, a1] and \ ++ * B: [b0, b1] is given by: \ ++ * \ ++ * a0 <= b1 && b0 <= a1 \ ++ * \ ++ * ... where A holds the lock range and B holds the smallest \ ++ * 'start' and largest 'last' in the tree. For the later, we \ ++ * rely on the root node, which by augmented interval tree \ ++ * property, holds the largest value in its last-in-subtree. \ ++ * This allows mitigating some of the tree walk overhead for \ ++ * for non-intersecting ranges, maintained and consulted in O(1). \ ++ */ \ ++ node = rb_entry(root->rb_root.rb_node, ITSTRUCT, ITRB); \ ++ if (node->ITSUBTREE < start) \ ++ return NULL; \ ++ \ ++ leftmost = rb_entry(root->rb_leftmost, ITSTRUCT, ITRB); \ ++ if (ITSTART(leftmost) > last) \ ++ return NULL; \ ++ \ ++ return ITPREFIX ## _subtree_search(node, start, last); \ ++} \ ++ \ ++ITSTATIC ITSTRUCT * \ ++ITPREFIX ## _iter_next(ITSTRUCT *node, ITTYPE start, ITTYPE last) \ ++{ \ ++ struct rb_node *rb = node->ITRB.rb_right, *prev; \ ++ \ ++ while (true) { \ ++ /* \ ++ * Loop invariants: \ ++ * Cond1: ITSTART(node) <= last \ ++ * rb == node->ITRB.rb_right \ ++ * \ ++ * First, search right subtree if suitable \ ++ */ \ ++ if (rb) { \ ++ ITSTRUCT *right = rb_entry(rb, ITSTRUCT, ITRB); \ ++ if (start <= right->ITSUBTREE) \ ++ return ITPREFIX ## _subtree_search(right, \ ++ start, last); \ ++ } \ ++ \ ++ /* Move up the tree until we come from a node's left child */ \ ++ do { \ ++ rb = rb_parent(&node->ITRB); \ ++ if (!rb) \ ++ return NULL; \ ++ prev = &node->ITRB; \ ++ node = rb_entry(rb, ITSTRUCT, ITRB); \ ++ rb = node->ITRB.rb_right; \ ++ } while (prev == rb); \ ++ \ ++ /* Check if the node intersects [start;last] */ \ ++ if (last < ITSTART(node)) /* !Cond1 */ \ ++ return NULL; \ ++ else if (start <= ITLAST(node)) /* Cond2 */ \ ++ return node; \ ++ } \ ++} +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 7e24b09b1163a..89b37cd4ab1dc 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -50,38 +51,22 @@ static inline u32 str_hash(const char *str) + __elf_table(name); \ + }) + +-static bool symbol_to_offset(struct rb_node *a, const struct rb_node *b) ++static inline unsigned long __sym_start(struct symbol *s) + { +- struct symbol *sa = rb_entry(a, struct symbol, node); +- struct symbol *sb = rb_entry(b, struct symbol, node); +- +- if (sa->offset < sb->offset) +- return true; +- if (sa->offset > sb->offset) +- return false; +- +- if (sa->len < sb->len) +- return true; +- if (sa->len > sb->len) +- return false; +- +- sa->alias = sb; +- +- return false; ++ return s->offset; + } + +-static int symbol_by_offset(const void *key, const struct rb_node *node) ++static inline unsigned long __sym_last(struct symbol *s) + { +- const struct symbol *s = rb_entry(node, struct symbol, node); +- const unsigned long *o = key; ++ return s->offset + s->len - 1; ++} + +- if (*o < s->offset) +- return -1; +- if (*o >= s->offset + s->len) +- return 1; ++INTERVAL_TREE_DEFINE(struct symbol, node, unsigned long, __subtree_last, ++ __sym_start, __sym_last, static, __sym) + +- return 0; +-} ++#define __sym_for_each(_iter, _tree, _start, _end) \ ++ for (_iter = __sym_iter_first((_tree), (_start), (_end)); \ ++ _iter; _iter = __sym_iter_next(_iter, (_start), (_end))) + + struct symbol_hole { + unsigned long key; +@@ -147,13 +132,12 @@ static struct symbol *find_symbol_by_index(struct elf *elf, unsigned int idx) + + struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) + { +- struct rb_node *node; +- +- rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { +- struct symbol *s = rb_entry(node, struct symbol, node); ++ struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; ++ struct symbol *iter; + +- if (s->offset == offset && s->type != STT_SECTION) +- return s; ++ __sym_for_each(iter, tree, offset, offset) { ++ if (iter->offset == offset && iter->type != STT_SECTION) ++ return iter; + } + + return NULL; +@@ -161,13 +145,12 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset) + + struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) + { +- struct rb_node *node; ++ struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; ++ struct symbol *iter; + +- rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { +- struct symbol *s = rb_entry(node, struct symbol, node); +- +- if (s->offset == offset && s->type == STT_FUNC) +- return s; ++ __sym_for_each(iter, tree, offset, offset) { ++ if (iter->offset == offset && iter->type == STT_FUNC) ++ return iter; + } + + return NULL; +@@ -175,13 +158,12 @@ struct symbol *find_func_by_offset(struct section *sec, unsigned long offset) + + struct symbol *find_symbol_containing(const struct section *sec, unsigned long offset) + { +- struct rb_node *node; +- +- rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { +- struct symbol *s = rb_entry(node, struct symbol, node); ++ struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; ++ struct symbol *iter; + +- if (s->type != STT_SECTION) +- return s; ++ __sym_for_each(iter, tree, offset, offset) { ++ if (iter->type != STT_SECTION) ++ return iter; + } + + return NULL; +@@ -202,7 +184,7 @@ int find_symbol_hole_containing(const struct section *sec, unsigned long offset) + /* + * Find the rightmost symbol for which @offset is after it. + */ +- n = rb_find(&hole, &sec->symbol_tree, symbol_hole_by_offset); ++ n = rb_find(&hole, &sec->symbol_tree.rb_root, symbol_hole_by_offset); + + /* found a symbol that contains @offset */ + if (n) +@@ -224,13 +206,12 @@ int find_symbol_hole_containing(const struct section *sec, unsigned long offset) + + struct symbol *find_func_containing(struct section *sec, unsigned long offset) + { +- struct rb_node *node; +- +- rb_for_each(node, &offset, &sec->symbol_tree, symbol_by_offset) { +- struct symbol *s = rb_entry(node, struct symbol, node); ++ struct rb_root_cached *tree = (struct rb_root_cached *)&sec->symbol_tree; ++ struct symbol *iter; + +- if (s->type == STT_FUNC) +- return s; ++ __sym_for_each(iter, tree, offset, offset) { ++ if (iter->type == STT_FUNC) ++ return iter; + } + + return NULL; +@@ -373,6 +354,7 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + { + struct list_head *entry; + struct rb_node *pnode; ++ struct symbol *iter; + + INIT_LIST_HEAD(&sym->pv_target); + sym->alias = sym; +@@ -386,7 +368,12 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->offset = sym->sym.st_value; + sym->len = sym->sym.st_size; + +- rb_add(&sym->node, &sym->sec->symbol_tree, symbol_to_offset); ++ __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { ++ if (iter->offset == sym->offset && iter->type == sym->type) ++ iter->alias = sym; ++ } ++ ++ __sym_insert(sym, &sym->sec->symbol_tree); + pnode = rb_prev(&sym->node); + if (pnode) + entry = &rb_entry(pnode, struct symbol, node)->list; +@@ -401,7 +388,7 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + * can exist within a function, confusing the sorting. + */ + if (!sym->len) +- rb_erase(&sym->node, &sym->sec->symbol_tree); ++ __sym_remove(sym, &sym->sec->symbol_tree); + } + + static int read_symbols(struct elf *elf) +diff --git a/tools/objtool/include/objtool/elf.h b/tools/objtool/include/objtool/elf.h +index 5d4a841fbd311..fdb6c96aa0a5a 100644 +--- a/tools/objtool/include/objtool/elf.h ++++ b/tools/objtool/include/objtool/elf.h +@@ -30,7 +30,7 @@ struct section { + struct hlist_node hash; + struct hlist_node name_hash; + GElf_Shdr sh; +- struct rb_root symbol_tree; ++ struct rb_root_cached symbol_tree; + struct list_head symbol_list; + struct list_head reloc_list; + struct section *base, *reloc; +@@ -53,6 +53,7 @@ struct symbol { + unsigned char bind, type; + unsigned long offset; + unsigned int len; ++ unsigned long __subtree_last; + struct symbol *pfunc, *cfunc, *alias; + u8 uaccess_safe : 1; + u8 static_call_tramp : 1; +-- +2.51.0 + diff --git a/queue-6.1/objtool-fix-weak-symbol-detection.patch b/queue-6.1/objtool-fix-weak-symbol-detection.patch new file mode 100644 index 0000000000..ff70704239 --- /dev/null +++ b/queue-6.1/objtool-fix-weak-symbol-detection.patch @@ -0,0 +1,65 @@ +From eaaa91255a4676a8e732a84d13ad70cfa146ab8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:27 -0700 +Subject: objtool: Fix weak symbol detection + +From: Josh Poimboeuf + +[ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] + +find_symbol_hole_containing() fails to find a symbol hole (aka stripped +weak symbol) if its section has no symbols before the hole. This breaks +weak symbol detection if -ffunction-sections is enabled. + +Fix that by allowing the interval tree to contain section symbols, which +are always at offset zero for a given section. + +Fixes a bunch of (-ffunction-sections) warnings like: + + vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction + +Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") +Acked-by: Petr Mladek +Tested-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 89b37cd4ab1dc..905253421e8c8 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -74,7 +74,7 @@ struct symbol_hole { + }; + + /* +- * Find !section symbol where @offset is after it. ++ * Find the last symbol before @offset. + */ + static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + { +@@ -85,8 +85,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + return -1; + + if (sh->key >= s->offset + s->len) { +- if (s->type != STT_SECTION) +- sh->sym = s; ++ sh->sym = s; + return 1; + } + +@@ -369,7 +368,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->len = sym->sym.st_size; + + __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { +- if (iter->offset == sym->offset && iter->type == sym->type) ++ if (iter->offset == sym->offset && iter->type == sym->type && ++ iter->len == sym->len) + iter->alias = sym; + } + +-- +2.51.0 + diff --git a/queue-6.1/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-6.1/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..749b7952a8 --- /dev/null +++ b/queue-6.1/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From 57587b3b9ba3067c943b04ff38969df565fb8d21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 866d57dfe9f74..1ac42064657d5 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-6.1/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-6.1/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..e0c6a34394 --- /dev/null +++ b/queue-6.1/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From 2297dc2097e2ba659cff54cfa7088213a7db0b7c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index a871ae7eb59ec..44254f31b5ac1 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -75,7 +75,7 @@ + #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-6.1/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-6.1/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..3d0b0a3401 --- /dev/null +++ b/queue-6.1/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 1c31cabe4e3472c245dde4131514e88ce3523dbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index c868d36f1177b..35f807524f56f 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1342,6 +1342,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-6.1/perf-record-skip-synthesize-event-when-open-evsel-fa.patch b/queue-6.1/perf-record-skip-synthesize-event-when-open-evsel-fa.patch new file mode 100644 index 0000000000..0a64f45e7b --- /dev/null +++ b/queue-6.1/perf-record-skip-synthesize-event-when-open-evsel-fa.patch @@ -0,0 +1,71 @@ +From 838f219c890b8f1d2d478551037c398cc8b4ad40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:50:43 +0800 +Subject: perf record: skip synthesize event when open evsel failed + +From: Shuai Xue + +[ Upstream commit 163e5f2b96632b7fb2eaa965562aca0dbdf9f996 ] + +When using perf record with the `--overwrite` option, a segmentation fault +occurs if an event fails to open. For example: + + perf record -e cycles-ct -F 1000 -a --overwrite + Error: + cycles-ct:H: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + perf: Segmentation fault + #0 0x6466b6 in dump_stack debug.c:366 + #1 0x646729 in sighandler_dump_stack debug.c:378 + #2 0x453fd1 in sigsegv_handler builtin-record.c:722 + #3 0x7f8454e65090 in __restore_rt libc-2.32.so[54090] + #4 0x6c5671 in __perf_event__synthesize_id_index synthetic-events.c:1862 + #5 0x6c5ac0 in perf_event__synthesize_id_index synthetic-events.c:1943 + #6 0x458090 in record__synthesize builtin-record.c:2075 + #7 0x45a85a in __cmd_record builtin-record.c:2888 + #8 0x45deb6 in cmd_record builtin-record.c:4374 + #9 0x4e5e33 in run_builtin perf.c:349 + #10 0x4e60bf in handle_internal_command perf.c:401 + #11 0x4e6215 in run_argv perf.c:448 + #12 0x4e653a in main perf.c:555 + #13 0x7f8454e4fa72 in __libc_start_main libc-2.32.so[3ea72] + #14 0x43a3ee in _start ??:0 + +The --overwrite option implies --tail-synthesize, which collects non-sample +events reflecting the system status when recording finishes. However, when +evsel opening fails (e.g., unsupported event 'cycles-ct'), session->evlist +is not initialized and remains NULL. The code unconditionally calls +record__synthesize() in the error path, which iterates through the NULL +evlist pointer and causes a segfault. + +To fix it, move the record__synthesize() call inside the error check block, so +it's only called when there was no error during recording, ensuring that evlist +is properly initialized. + +Fixes: 4ea648aec019 ("perf record: Add --tail-synthesize option") +Signed-off-by: Shuai Xue +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c +index a257a30a42efd..fa2a066005ad0 100644 +--- a/tools/perf/builtin-record.c ++++ b/tools/perf/builtin-record.c +@@ -2793,11 +2793,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) + rec->bytes_written += off_cpu_write(rec->session); + + record__read_lost_samples(rec); +- record__synthesize(rec, true); + /* this will be recalculated during process_buildids() */ + rec->samples = 0; + + if (!err) { ++ record__synthesize(rec, true); + if (!rec->timestamp_filename) { + record__finish_output(rec); + } else { +-- +2.51.0 + diff --git a/queue-6.1/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-6.1/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..03e253b2b6 --- /dev/null +++ b/queue-6.1/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From 2e9462fb9c49af348f0234f39e4307a9ec97768a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 98014f9375686..b434f2398df5a 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -904,11 +904,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + if (ndso == NULL) +-- +2.51.0 + diff --git a/queue-6.1/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-6.1/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..2da870ea58 --- /dev/null +++ b/queue-6.1/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From c448775695e8c9f148bed16bcd3980a8a76ab416 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 2cb5b1f715b62..b1bc81bef4083 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3779,7 +3779,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-6.1/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-6.1/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..6bd43eebfb --- /dev/null +++ b/queue-6.1/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From aa099c662dc80b7818d7675969d124f5f550530c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index 2fabb6a7d2415..d9ad8aac58098 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2560,7 +2560,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2581,12 +2581,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-6.1/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch b/queue-6.1/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch new file mode 100644 index 0000000000..e5e631109d --- /dev/null +++ b/queue-6.1/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch @@ -0,0 +1,94 @@ +From 2ec0f033dfec398f697abca4ef84e4f84ef15464 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 16:58:05 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Fix an error handling path in + rcar_gen3_phy_usb2_probe() + +From: Christophe JAILLET + +[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ] + +If an error occurs after the reset_control_deassert(), +reset_control_assert() must be called, as already done in the remove +function. + +Use devm_add_action_or_reset() to add the missing call and simplify the +.remove() function accordingly. + +While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. + +[claudiu.beznea: removed "struct reset_control *rstc = data;" from + rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] + +Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") +Signed-off-by: Christophe JAILLET +Reviewed-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Tested-by: Wolfram Sang +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index 024cc5ce68a37..c7d6321981e06 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -119,7 +119,6 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; +- struct reset_control *rstc; + struct work_struct work; + spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; +@@ -660,21 +659,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static void rcar_gen3_reset_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) + { + struct device *dev = channel->dev; ++ struct reset_control *rstc; + int ret; + u32 val; + +- channel->rstc = devm_reset_control_array_get_shared(dev); +- if (IS_ERR(channel->rstc)) +- return PTR_ERR(channel->rstc); ++ rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(rstc)) ++ return PTR_ERR(rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + +- ret = reset_control_deassert(channel->rstc); ++ ret = reset_control_deassert(rstc); ++ if (ret) ++ goto rpm_put; ++ ++ ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); + if (ret) + goto rpm_put; + +@@ -816,7 +825,6 @@ static int rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + +- reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + + return 0; +-- +2.51.0 + diff --git a/queue-6.1/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-6.1/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..3980c09082 --- /dev/null +++ b/queue-6.1/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From 9d758854f0b28ba12a55b646b5e07dbc15aa79c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index b81297084f097..0659cd3aa3a5a 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -490,7 +490,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -554,9 +555,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-6.1/pinctrl-single-fix-pin_config_bias_disable-handling.patch b/queue-6.1/pinctrl-single-fix-pin_config_bias_disable-handling.patch new file mode 100644 index 0000000000..c437a7c7a5 --- /dev/null +++ b/queue-6.1/pinctrl-single-fix-pin_config_bias_disable-handling.patch @@ -0,0 +1,95 @@ +From 97cae848ec6ed14c19fbbf7ac93762cfaec1c25e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 12:06:34 +0100 +Subject: pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling + +From: Matthijs Kooijman + +[ Upstream commit b5fe46efc147516a908d2d31bf40eb858ab76d51 ] + +The pinctrl-single driver handles pin_config_set by looking up the +requested setting in a DT-defined lookup table, which defines what bits +correspond to each setting. There is no way to add +PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead +code to disable the bias by applying the disable values of both the +pullup and pulldown entries in the table. + +However, this code is inside the table-lookup loop, so it would only +execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, +which can never exist, so this code never runs. + +This commit lifts the offending code out of the loop, so it just +executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, +skippipng the table lookup loop. + +This also introduces a new `param` variable to make the code slightly +more readable. + +This bug seems to have existed when this code was first merged in commit +9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier +versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in +the lookup table, but that was removed, which is probably how this bug +was introduced. + +Signed-off-by: Matthijs Kooijman +Reviewed-by: Haojian Zhuang +Reviewed-by: Tony Lindgren +Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> +Signed-off-by: Linus Walleij +Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable") +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index a72911e8ea82d..b81297084f097 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -557,21 +557,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + unsigned offset = 0, shift = 0, i, data, ret; + u32 arg; + int j; ++ enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (j = 0; j < num_configs; j++) { ++ param = pinconf_to_config_param(configs[j]); ++ ++ /* BIAS_DISABLE has no entry in the func->conf table */ ++ if (param == PIN_CONFIG_BIAS_DISABLE) { ++ /* This just disables all bias entries */ ++ pcs_pinconf_clear_bias(pctldev, pin); ++ continue; ++ } ++ + for (i = 0; i < func->nconfs; i++) { +- if (pinconf_to_config_param(configs[j]) +- != func->conf[i].param) ++ if (param != func->conf[i].param) + continue; + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset); + arg = pinconf_to_config_argument(configs[j]); +- switch (func->conf[i].param) { ++ switch (param) { + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_DRIVE_STRENGTH: +@@ -583,9 +592,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + data |= (arg << shift) & func->conf[i].mask; + break; + /* 4 parameters */ +- case PIN_CONFIG_BIAS_DISABLE: +- pcs_pinconf_clear_bias(pctldev, pin); +- break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (arg) { +-- +2.51.0 + diff --git a/queue-6.1/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.1/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..a4333653cf --- /dev/null +++ b/queue-6.1/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From 225e9322070450257314d5b1cfa357b80a6caa8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 661eb0c1f7972..2b8b7d3eec9b1 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1554,7 +1554,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-6.1/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-6.1/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..2e8c86b6cd --- /dev/null +++ b/queue-6.1/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From 92db73392d596b65ea2c441b4ab2579bef2a04c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9d1a7fbcaed42..50b9636945599 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -365,7 +365,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-6.1/power-supply-cw2015-check-devm_delayed_work_autocanc.patch b/queue-6.1/power-supply-cw2015-check-devm_delayed_work_autocanc.patch new file mode 100644 index 0000000000..f4efbe4aca --- /dev/null +++ b/queue-6.1/power-supply-cw2015-check-devm_delayed_work_autocanc.patch @@ -0,0 +1,46 @@ +From 591b6c8642e7a047afaad0349ef84a61d538ed4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:07:11 +0300 +Subject: power: supply: cw2015: Check devm_delayed_work_autocancel() return + code + +From: Ivan Abramov + +[ Upstream commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 ] + +Since devm_delayed_work_autocancel() may fail, add return code check and +exit cw_bat_probe() on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/cw2015_battery.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index ae6f46b452101..e4783f009a384 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -702,7 +702,13 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ if (ret) { ++ dev_err_probe(&client->dev, ret, ++ "Failed to register delayed work\n"); ++ return ret; ++ } ++ + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +-- +2.51.0 + diff --git a/queue-6.1/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-6.1/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..a5d19ad561 --- /dev/null +++ b/queue-6.1/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From 9a65991c016894e904be6831ab7302eb95f056e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 82e31066c746e..bbae77982d086 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.1/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-6.1/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..38113311d1 --- /dev/null +++ b/queue-6.1/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From 4e31cab063eb55afcd220704738b22c0d4a808b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index d4fc546762db4..ca0f0abc49262 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -310,10 +310,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -356,10 +355,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-6.1/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-6.1/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..736362b223 --- /dev/null +++ b/queue-6.1/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From e1f72f83aa08b5afc16d467acc26ed3e3223f63b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index 9a601587836b2..ee5e1dfe7932a 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-6.1/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-6.1/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..c1ffe5c701 --- /dev/null +++ b/queue-6.1/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From 23b43251333070336a241f13dd40929edfd9ffd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index 36d7b36c60c76..79d3779e1c7ad 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-6.1/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-6.1/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..2f43e0de04 --- /dev/null +++ b/queue-6.1/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From 837a95673e35ec01d4c15d2df7c475d025ec9231 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 50b8594be31d8..4541d63d57c40 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -35,29 +35,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return container_of(chip, struct bcm2835_pwm, chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -109,6 +86,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -126,8 +106,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + .owner = THIS_MODULE, + }; +-- +2.51.0 + diff --git a/queue-6.1/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-6.1/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..4a3e3dc22f --- /dev/null +++ b/queue-6.1/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From 85748ea0a588fe9fb1c1a6d4d0b7c7622e5cb7a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index d8afdb8784c1c..c89dd30fa3dff 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-6.1/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-6.1/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..5852ff21b2 --- /dev/null +++ b/queue-6.1/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From 3fadacc24b259b04c4d707973d5dc963dfd71639 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index 8dd9e44ed2a4c..d69ebab5c2111 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-6.1/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-6.1/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..1510941130 --- /dev/null +++ b/queue-6.1/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From e1e670c3c7ac11482827245b5aae2b7876cca06a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index d98bfb83c3b4b..9525144a4c4e5 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3303,11 +3303,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3318,6 +3320,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-6.1/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-6.1/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..de57f87e75 --- /dev/null +++ b/queue-6.1/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From 24c43278d629fd343d350a7846c4013f5128662e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 8b3b9b798676b..51ec4620ca821 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1448,7 +1448,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-6.1/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-6.1/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..87759c9534 --- /dev/null +++ b/queue-6.1/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From dec2c9375f04751b616b8fbe1df7d17463ca672d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 7e6ff7e72784b..436764329f63b 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1660,6 +1660,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1679,11 +1681,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.1/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-6.1/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..53dca37f01 --- /dev/null +++ b/queue-6.1/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 4adaac34c64821f65b6415aad24ae682b649e780 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 436764329f63b..7b1d60628a001 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1977,6 +1977,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1985,6 +1986,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2463,22 +2465,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2498,11 +2504,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-6.1/reinstate-resource-avoid-unnecessary-lookups-in-find.patch b/queue-6.1/reinstate-resource-avoid-unnecessary-lookups-in-find.patch new file mode 100644 index 0000000000..0dccd9b1a6 --- /dev/null +++ b/queue-6.1/reinstate-resource-avoid-unnecessary-lookups-in-find.patch @@ -0,0 +1,85 @@ +From cec9096e730e3dc14828444fff33f9c185850787 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:53:49 +0000 +Subject: Reinstate "resource: avoid unnecessary lookups in + find_next_iomem_res()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilias Stamatis + +[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ] + +Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only +logic") removed an optimization introduced by commit 756398750e11 +("resource: avoid unnecessary lookups in find_next_iomem_res()"). That +was not called out in the message of the first commit explicitly so it's +not entirely clear whether removing the optimization happened +inadvertently or not. + +As the original commit message of the optimization explains there is no +point considering the children of a subtree in find_next_iomem_res() if +the top level range does not match. + +Reinstating the optimization results in performance improvements in +systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem +in such platforms takes 700-1500μs without the optimisation and 10-50μs +with the optimisation. + +Note that even though commit 97523a4edb7b removed the 'sibling_only' +parameter from next_resource(), newer kernels have basically reinstated it +under the name 'skip_children'. + +Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u +Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") +Signed-off-by: Ilias Stamatis +Acked-by: David Hildenbrand (Red Hat) +Cc: Andriy Shevchenko +Cc: Baoquan He +Cc: "Huang, Ying" +Cc: Nadav Amit +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 1170ed58404fb..f39b9fe738d14 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -336,6 +336,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + unsigned long flags, unsigned long desc, + struct resource *res) + { ++ /* Skip children until we find a top level range that matches */ ++ bool skip_children = true; + struct resource *p; + + if (!res) +@@ -346,7 +348,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for_each_resource(&iomem_resource, p, false) { ++ for_each_resource(&iomem_resource, p, skip_children) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -357,6 +359,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + ++ /* ++ * We found a top level range that matches what we are looking ++ * for. Time to start checking children too. ++ */ ++ skip_children = false; ++ + /* Found a match, break */ + if (is_type_match(p, flags, desc)) + break; +-- +2.51.0 + diff --git a/queue-6.1/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-6.1/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..fb882a32ab --- /dev/null +++ b/queue-6.1/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From bcae2e5fefdeccc08af73fd654956b32400203b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index ba24d745b2d65..2bb94cdd60136 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.1/resource-introduce-is_type_match-helper-and-use-it.patch b/queue-6.1/resource-introduce-is_type_match-helper-and-use-it.patch new file mode 100644 index 0000000000..216db76e26 --- /dev/null +++ b/queue-6.1/resource-introduce-is_type_match-helper-and-use-it.patch @@ -0,0 +1,91 @@ +From 907e990a2a77074bbe161a5259b391972ce5475b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:35 +0300 +Subject: resource: introduce is_type_match() helper and use it + +From: Andy Shevchenko + +[ Upstream commit ba1eccc114ffc62c4495a5e15659190fa2c42308 ] + +There are already a couple of places where we may replace a few lines of +code by calling a helper, which increases readability while deduplicating +the code. + +Introduce is_type_match() helper and use it. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 20cb54f387e71..1170ed58404fb 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -310,6 +310,11 @@ int release_resource(struct resource *old) + + EXPORT_SYMBOL(release_resource); + ++static bool is_type_match(struct resource *p, unsigned long flags, unsigned long desc) ++{ ++ return (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc); ++} ++ + /** + * find_next_iomem_res - Finds the lowest iomem resource that covers part of + * [@start..@end]. +@@ -352,13 +357,9 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + +- if ((p->flags & flags) != flags) +- continue; +- if ((desc != IORES_DESC_NONE) && (desc != p->desc)) +- continue; +- + /* Found a match, break */ +- break; ++ if (is_type_match(p, flags, desc)) ++ break; + } + + if (p) { +@@ -501,7 +502,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + int type = 0; int other = 0; + struct resource *p, *dp; + struct resource res, o; +- bool is_type, covered; ++ bool covered; + + res.start = start; + res.end = start + size - 1; +@@ -509,9 +510,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for (p = parent->child; p ; p = p->sibling) { + if (!resource_intersection(p, &res, &o)) + continue; +- is_type = (p->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == p->desc); +- if (is_type) { ++ if (is_type_match(p, flags, desc)) { + type++; + continue; + } +@@ -531,9 +530,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +- is_type = (dp->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == dp->desc); +- if (is_type) { ++ if (is_type_match(dp, flags, desc)) { + type++; + /* + * Range from 'o.start' to 'dp->start' +-- +2.51.0 + diff --git a/queue-6.1/resource-replace-open-coded-resource_intersection.patch b/queue-6.1/resource-replace-open-coded-resource_intersection.patch new file mode 100644 index 0000000000..4210efb43a --- /dev/null +++ b/queue-6.1/resource-replace-open-coded-resource_intersection.patch @@ -0,0 +1,88 @@ +From 87d3fd2456264761a9736469943f1dd0d5fc87f0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:34 +0300 +Subject: resource: replace open coded resource_intersection() + +From: Andy Shevchenko + +[ Upstream commit 5c1edea773c98707fbb23d1df168bcff52f61e4b ] + +Patch series "resource: A couple of cleanups". + +A couple of ad-hoc cleanups since there was a recent development of +the code in question. No functional changes intended. + +This patch (of 2): + +__region_intersects() uses open coded resource_intersection(). Replace it +with existing API which also make more clear what we are checking. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-1-andriy.shevchenko@linux.intel.com +Link: https://lkml.kernel.org/r/20240925154355.1170859-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 6703fd889ae1b..20cb54f387e71 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -498,17 +498,16 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + size_t size, unsigned long flags, + unsigned long desc) + { +- resource_size_t ostart, oend; + int type = 0; int other = 0; + struct resource *p, *dp; ++ struct resource res, o; + bool is_type, covered; +- struct resource res; + + res.start = start; + res.end = start + size - 1; + + for (p = parent->child; p ; p = p->sibling) { +- if (!resource_overlaps(p, &res)) ++ if (!resource_intersection(p, &res, &o)) + continue; + is_type = (p->flags & flags) == flags && + (desc == IORES_DESC_NONE || desc == p->desc); +@@ -529,8 +528,6 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + * |-- "System RAM" --||-- "CXL Window 0a" --| + */ + covered = false; +- ostart = max(res.start, p->start); +- oend = min(res.end, p->end); + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +@@ -539,17 +536,17 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + if (is_type) { + type++; + /* +- * Range from 'ostart' to 'dp->start' ++ * Range from 'o.start' to 'dp->start' + * isn't covered by matched resource. + */ +- if (dp->start > ostart) ++ if (dp->start > o.start) + break; +- if (dp->end >= oend) { ++ if (dp->end >= o.end) { + covered = true; + break; + } + /* Remove covered range */ +- ostart = max(ostart, dp->end + 1); ++ o.start = max(o.start, dp->end + 1); + } + } + if (!covered) +-- +2.51.0 + diff --git a/queue-6.1/resource-replace-printk-kern_warning-by-pr_warn-prin.patch b/queue-6.1/resource-replace-printk-kern_warning-by-pr_warn-prin.patch new file mode 100644 index 0000000000..aa61a77970 --- /dev/null +++ b/queue-6.1/resource-replace-printk-kern_warning-by-pr_warn-prin.patch @@ -0,0 +1,90 @@ +From 7d84a6015972b06525acf32e8d1d3cd523c207f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Nov 2022 17:56:17 +0200 +Subject: resource: Replace printk(KERN_WARNING) by pr_warn(), printk() by + pr_info() + +From: Andy Shevchenko + +[ Upstream commit 2a4e628570d42fcc13a94f1acf25e3cfeaec08f6 ] + +Replace printk(KERN_WARNING) by pr_warn() and printk() by pr_info(). + +While at it, use %pa for the resource_size_t variables. With that, +for the sake of consistency, introduce a temporary variable for +the end address in iomem_map_sanity_check() like it's done in another +function in the same module. + +Signed-off-by: Andy Shevchenko +Reviewed-by: Rafael J. Wysocki +Link: https://lore.kernel.org/r/20221109155618.42276-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 17 +++++++---------- + 1 file changed, 7 insertions(+), 10 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index ca0a59f5bc2bd..eb713a984c749 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -930,7 +930,7 @@ void insert_resource_expand_to_fit(struct resource *root, struct resource *new) + if (conflict->end > new->end) + new->end = conflict->end; + +- printk("Expanded resource %s due to conflict with %s\n", new->name, conflict->name); ++ pr_info("Expanded resource %s due to conflict with %s\n", new->name, conflict->name); + } + write_unlock(&resource_lock); + } +@@ -1325,9 +1325,7 @@ void __release_region(struct resource *parent, resource_size_t start, + + write_unlock(&resource_lock); + +- printk(KERN_WARNING "Trying to free nonexistent resource " +- "<%016llx-%016llx>\n", (unsigned long long)start, +- (unsigned long long)end); ++ pr_warn("Trying to free nonexistent resource <%pa-%pa>\n", &start, &end); + } + EXPORT_SYMBOL(__release_region); + +@@ -1686,6 +1684,7 @@ __setup("reserve=", reserve_setup); + int iomem_map_sanity_check(resource_size_t addr, unsigned long size) + { + struct resource *p = &iomem_resource; ++ resource_size_t end = addr + size - 1; + int err = 0; + loff_t l; + +@@ -1695,12 +1694,12 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) + * We can probably skip the resources without + * IORESOURCE_IO attribute? + */ +- if (p->start >= addr + size) ++ if (p->start > end) + continue; + if (p->end < addr) + continue; + if (PFN_DOWN(p->start) <= PFN_DOWN(addr) && +- PFN_DOWN(p->end) >= PFN_DOWN(addr + size - 1)) ++ PFN_DOWN(p->end) >= PFN_DOWN(end)) + continue; + /* + * if a resource is "BUSY", it's not a hardware resource +@@ -1711,10 +1710,8 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size) + if (p->flags & IORESOURCE_BUSY) + continue; + +- printk(KERN_WARNING "resource sanity check: requesting [mem %#010llx-%#010llx], which spans more than %s %pR\n", +- (unsigned long long)addr, +- (unsigned long long)(addr + size - 1), +- p->name, p); ++ pr_warn("resource sanity check: requesting [mem %pa-%pa], which spans more than %s %pR\n", ++ &addr, &end, p->name, p); + err = -1; + break; + } +-- +2.51.0 + diff --git a/queue-6.1/resource-reuse-for_each_resource-macro.patch b/queue-6.1/resource-reuse-for_each_resource-macro.patch new file mode 100644 index 0000000000..e4885d6485 --- /dev/null +++ b/queue-6.1/resource-reuse-for_each_resource-macro.patch @@ -0,0 +1,101 @@ +From 91b47833198776ce1aa63599d67741a391718d5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 19:53:10 +0300 +Subject: resource: Reuse for_each_resource() macro + +From: Andy Shevchenko + +[ Upstream commit 441f0dd8fa035a2c7cfe972047bb905d3be05c1b ] + +We have a few places where for_each_resource() is open coded. +Replace that by the macro. This makes code easier to read and +understand. + +With this, compile r_next() only for CONFIG_PROC_FS=y. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230912165312.402422-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 34 +++++++++++++++++++--------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index eb713a984c749..6703fd889ae1b 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -77,13 +77,6 @@ static struct resource *next_resource_skip_children(struct resource *p) + (_p) = (_skip_children) ? next_resource_skip_children(_p) : \ + next_resource(_p)) + +-static void *r_next(struct seq_file *m, void *v, loff_t *pos) +-{ +- struct resource *p = v; +- (*pos)++; +- return (void *)next_resource(p); +-} +- + #ifdef CONFIG_PROC_FS + + enum { MAX_IORES_LEVEL = 5 }; +@@ -91,14 +84,26 @@ enum { MAX_IORES_LEVEL = 5 }; + static void *r_start(struct seq_file *m, loff_t *pos) + __acquires(resource_lock) + { +- struct resource *p = pde_data(file_inode(m->file)); +- loff_t l = 0; ++ struct resource *root = pde_data(file_inode(m->file)); ++ struct resource *p; ++ loff_t l = *pos; ++ + read_lock(&resource_lock); +- for (p = p->child; p && l < *pos; p = r_next(m, p, &l)) +- ; ++ for_each_resource(root, p, false) { ++ if (l-- == 0) ++ break; ++ } ++ + return p; + } + ++static void *r_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct resource *p = v; ++ (*pos)++; ++ return (void *)next_resource(p); ++} ++ + static void r_stop(struct seq_file *m, void *v) + __releases(resource_lock) + { +@@ -336,7 +341,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for (p = iomem_resource.child; p; p = next_resource(p)) { ++ for_each_resource(&iomem_resource, p, false) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -1683,13 +1688,12 @@ __setup("reserve=", reserve_setup); + */ + int iomem_map_sanity_check(resource_size_t addr, unsigned long size) + { +- struct resource *p = &iomem_resource; + resource_size_t end = addr + size - 1; ++ struct resource *p; + int err = 0; +- loff_t l; + + read_lock(&resource_lock); +- for (p = p->child; p ; p = r_next(NULL, p, &l)) { ++ for_each_resource(&iomem_resource, p, false) { + /* + * We can probably skip the resources without + * IORESOURCE_IO attribute? +-- +2.51.0 + diff --git a/queue-6.1/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch b/queue-6.1/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch new file mode 100644 index 0000000000..bc3b4244fe --- /dev/null +++ b/queue-6.1/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch @@ -0,0 +1,84 @@ +From 8dd542374ecdf12f3c8a00a7b76f5adf377848ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 21:35:43 +0800 +Subject: RISC-V: KVM: Fix guest page fault within HLV* instructions + +From: Fangyu Yu + +[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ] + +When executing HLV* instructions at the HS mode, a guest page fault +may occur when a g-stage page table migration between triggering the +virtual instruction exception and executing the HLV* instruction. + +This may be a corner case, and one simpler way to handle this is to +re-execute the instruction where the virtual instruction exception +occurred, and the guest page fault will be automatically handled. + +Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") +Signed-off-by: Fangyu Yu +Reviewed-by: Anup Patel +Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index 0bb52761a3f73..2dca4ab4fda88 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -393,6 +393,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + return (rc <= 0) ? rc : 1; + } + ++static bool is_load_guest_page_fault(unsigned long scause) ++{ ++ /** ++ * If a g-stage page fault occurs, the direct approach ++ * is to let the g-stage page fault handler handle it ++ * naturally, however, calling the g-stage page fault ++ * handler here seems rather strange. ++ * Considering this is a corner case, we can directly ++ * return to the guest and re-execute the same PC, this ++ * will trigger a g-stage page fault again and then the ++ * regular g-stage page fault handler will populate ++ * g-stage page table. ++ */ ++ return (scause == EXC_LOAD_GUEST_PAGE_FAULT); ++} ++ + /** + * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap + * +@@ -418,6 +434,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + return 1; +@@ -473,6 +491,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +@@ -599,6 +619,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +-- +2.51.0 + diff --git a/queue-6.1/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-6.1/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..290a60211b --- /dev/null +++ b/queue-6.1/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From 6d32c1f592566f14f92f9a358d329eabce5df610 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index c692b55dd1169..4bc5210df78a4 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -2196,15 +2196,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-6.1/s390-smp-fix-fallback-cpu-detection.patch b/queue-6.1/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..a0999de33b --- /dev/null +++ b/queue-6.1/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From 0044965180ba15f1a5984d6eca19850afd7cb838 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 436dbf4d743d8..8346cb75643ca 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -758,6 +758,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-6.1/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-6.1/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..7b80998850 --- /dev/null +++ b/queue-6.1/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From f4f35f1164c8b64d9d61dc23c0feef6d53629ff7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-6.1/scsi-smartpqi-add-abort-handler.patch b/queue-6.1/scsi-smartpqi-add-abort-handler.patch new file mode 100644 index 0000000000..7166f867a8 --- /dev/null +++ b/queue-6.1/scsi-smartpqi-add-abort-handler.patch @@ -0,0 +1,433 @@ +From 7baf8ea7b56454f03592d3b677013e487b3a8b86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 24 Aug 2023 10:58:05 -0500 +Subject: scsi: smartpqi: Add abort handler + +From: Kevin Barnett + +[ Upstream commit 153c45dd63ef33ffb3d78307db5aa6131b2fdefc ] + +Implement aborts as resets. + +Avoid I/O stalls across all devices attached to a controller when device +I/O requests time out. + +Reviewed-by: Mahesh Rajashekhara +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Reviewed-by: Mike McGowen +Signed-off-by: Kevin Barnett +Signed-off-by: Don Brace +Link: https://lore.kernel.org/r/20230824155812.789913-2-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: b518e86d1a70 ("scsi: smartpqi: Fix device resources accessed after device removal") +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi.h | 14 ++- + drivers/scsi/smartpqi/smartpqi_init.c | 171 ++++++++++++++++++++------ + 2 files changed, 149 insertions(+), 36 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index 6e2f08ac68166..5b40e7ad5e02d 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -1085,7 +1085,16 @@ struct pqi_stream_data { + u32 last_accessed; + }; + +-#define PQI_MAX_LUNS_PER_DEVICE 256 ++#define PQI_MAX_LUNS_PER_DEVICE 256 ++ ++struct pqi_tmf_work { ++ struct work_struct work_struct; ++ struct scsi_cmnd *scmd; ++ struct pqi_ctrl_info *ctrl_info; ++ struct pqi_scsi_dev *device; ++ u8 lun; ++ u8 scsi_opcode; ++}; + + struct pqi_scsi_dev { + int devtype; /* as reported by INQUIRY command */ +@@ -1110,6 +1119,7 @@ struct pqi_scsi_dev { + u8 ignore_device : 1; + bool aio_enabled; /* only valid for physical disks */ + bool in_remove; ++ bool in_reset[PQI_MAX_LUNS_PER_DEVICE]; + bool device_offline; + u8 vendor[8]; /* bytes 8-15 of inquiry data */ + u8 model[16]; /* bytes 16-31 of inquiry data */ +@@ -1148,6 +1158,8 @@ struct pqi_scsi_dev { + struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; + atomic_t scsi_cmds_outstanding[PQI_MAX_LUNS_PER_DEVICE]; + unsigned int raid_bypass_cnt; ++ ++ struct pqi_tmf_work tmf_work[PQI_MAX_LUNS_PER_DEVICE]; + }; + + /* VPD inquiry pages */ +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 4822b830ea371..5e39df2b6a4c0 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -48,6 +48,8 @@ + #define PQI_POST_RESET_DELAY_SECS 5 + #define PQI_POST_OFA_RESET_DELAY_UPON_TIMEOUT_SECS 10 + ++#define PQI_NO_COMPLETION ((void *)-1) ++ + MODULE_AUTHOR("Microchip"); + MODULE_DESCRIPTION("Driver for Microchip Smart Family Controller version " + DRIVER_VERSION); +@@ -96,6 +98,7 @@ static int pqi_ofa_host_memory_update(struct pqi_ctrl_info *ctrl_info); + static int pqi_device_wait_for_pending_io(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device, u8 lun, unsigned long timeout_msecs); + static void pqi_fail_all_outstanding_requests(struct pqi_ctrl_info *ctrl_info); ++static void pqi_tmf_worker(struct work_struct *work); + + /* for flags argument to pqi_submit_raid_request_synchronous() */ + #define PQI_SYNC_FLAGS_INTERRUPTABLE 0x1 +@@ -455,6 +458,21 @@ static inline bool pqi_device_in_remove(struct pqi_scsi_dev *device) + return device->in_remove; + } + ++static inline void pqi_device_reset_start(struct pqi_scsi_dev *device, u8 lun) ++{ ++ device->in_reset[lun] = true; ++} ++ ++static inline void pqi_device_reset_done(struct pqi_scsi_dev *device, u8 lun) ++{ ++ device->in_reset[lun] = false; ++} ++ ++static inline bool pqi_device_in_reset(struct pqi_scsi_dev *device, u8 lun) ++{ ++ return device->in_reset[lun]; ++} ++ + static inline int pqi_event_type_to_event_index(unsigned int event_type) + { + int index; +@@ -2171,6 +2189,15 @@ static inline bool pqi_is_device_added(struct pqi_scsi_dev *device) + return device->sdev != NULL; + } + ++static inline void pqi_init_device_tmf_work(struct pqi_scsi_dev *device) ++{ ++ unsigned int lun; ++ struct pqi_tmf_work *tmf_work; ++ ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ INIT_WORK(&tmf_work->work_struct, pqi_tmf_worker); ++} ++ + static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *new_device_list[], unsigned int num_new_devices) + { +@@ -2251,6 +2278,7 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, + list_add_tail(&device->add_list_entry, &add_list); + /* To prevent this device structure from being freed later. */ + device->keep_device = true; ++ pqi_init_device_tmf_work(device); + } + + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); +@@ -5896,6 +5924,7 @@ static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) + void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) + { + struct pqi_scsi_dev *device; ++ struct completion *wait; + + if (!scmd->device) { + set_host_byte(scmd, DID_NO_CONNECT); +@@ -5909,6 +5938,10 @@ void pqi_prep_for_scsi_done(struct scsi_cmnd *scmd) + } + + atomic_dec(&device->scsi_cmds_outstanding[scmd->device->lun]); ++ ++ wait = (struct completion *)xchg(&scmd->host_scribble, NULL); ++ if (wait != PQI_NO_COMPLETION) ++ complete(wait); + } + + static bool pqi_is_parity_write_stream(struct pqi_ctrl_info *ctrl_info, +@@ -5994,6 +6027,9 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm + u16 hw_queue; + struct pqi_queue_group *queue_group; + bool raid_bypassed; ++ u8 lun; ++ ++ scmd->host_scribble = PQI_NO_COMPLETION; + + device = scmd->device->hostdata; + +@@ -6003,7 +6039,9 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm + return 0; + } + +- atomic_inc(&device->scsi_cmds_outstanding[scmd->device->lun]); ++ lun = (u8)scmd->device->lun; ++ ++ atomic_inc(&device->scsi_cmds_outstanding[lun]); + + ctrl_info = shost_to_hba(shost); + +@@ -6013,7 +6051,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm + return 0; + } + +- if (pqi_ctrl_blocked(ctrl_info)) { ++ if (pqi_ctrl_blocked(ctrl_info) || pqi_device_in_reset(device, lun)) { + rc = SCSI_MLQUEUE_HOST_BUSY; + goto out; + } +@@ -6048,8 +6086,10 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm + } + + out: +- if (rc) +- atomic_dec(&device->scsi_cmds_outstanding[scmd->device->lun]); ++ if (rc) { ++ scmd->host_scribble = NULL; ++ atomic_dec(&device->scsi_cmds_outstanding[lun]); ++ } + + return rc; + } +@@ -6143,7 +6183,7 @@ static int pqi_wait_until_inbound_queues_empty(struct pqi_ctrl_info *ctrl_info) + } + + static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, +- struct pqi_scsi_dev *device) ++ struct pqi_scsi_dev *device, u8 lun) + { + unsigned int i; + unsigned int path; +@@ -6173,6 +6213,9 @@ static void pqi_fail_io_queued_for_device(struct pqi_ctrl_info *ctrl_info, + if (scsi_device != device) + continue; + ++ if ((u8)scmd->device->lun != lun) ++ continue; ++ + list_del(&io_request->request_list_entry); + set_host_byte(scmd, DID_RESET); + pqi_free_io_request(io_request); +@@ -6270,15 +6313,13 @@ static int pqi_wait_for_lun_reset_completion(struct pqi_ctrl_info *ctrl_info, + + #define PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS 30 + +-static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) ++static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun) + { + int rc; + struct pqi_io_request *io_request; + DECLARE_COMPLETION_ONSTACK(wait); + struct pqi_task_management_request *request; +- struct pqi_scsi_dev *device; + +- device = scmd->device->hostdata; + io_request = pqi_alloc_io_request(ctrl_info, NULL); + io_request->io_complete_callback = pqi_lun_reset_complete; + io_request->context = &wait; +@@ -6293,7 +6334,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd + memcpy(request->lun_number, device->scsi3addr, + sizeof(request->lun_number)); + if (!pqi_is_logical_device(device) && ctrl_info->multi_lun_device_supported) +- request->ml_device_lun_number = (u8)scmd->device->lun; ++ request->ml_device_lun_number = lun; + request->task_management_function = SOP_TASK_MANAGEMENT_LUN_RESET; + if (ctrl_info->tmf_iu_timeout_supported) + put_unaligned_le16(PQI_LUN_RESET_FIRMWARE_TIMEOUT_SECS, &request->timeout); +@@ -6301,7 +6342,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd + pqi_start_io(ctrl_info, &ctrl_info->queue_groups[PQI_DEFAULT_QUEUE_GROUP], RAID_PATH, + io_request); + +- rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, (u8)scmd->device->lun, &wait); ++ rc = pqi_wait_for_lun_reset_completion(ctrl_info, device, lun, &wait); + if (rc == 0) + rc = io_request->status; + +@@ -6315,18 +6356,16 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd + #define PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS (10 * 60 * 1000) + #define PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS (2 * 60 * 1000) + +-static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) ++static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun) + { + int reset_rc; + int wait_rc; + unsigned int retries; + unsigned long timeout_msecs; +- struct pqi_scsi_dev *device; + +- device = scmd->device->hostdata; + for (retries = 0;;) { +- reset_rc = pqi_lun_reset(ctrl_info, scmd); +- if (reset_rc == 0 || reset_rc == -ENODEV || ++retries > PQI_LUN_RESET_RETRIES) ++ reset_rc = pqi_lun_reset(ctrl_info, device, lun); ++ if (reset_rc == 0 || reset_rc == -ENODEV || reset_rc == -ENXIO || ++retries > PQI_LUN_RESET_RETRIES) + break; + msleep(PQI_LUN_RESET_RETRY_INTERVAL_MSECS); + } +@@ -6334,60 +6373,53 @@ static int pqi_lun_reset_with_retries(struct pqi_ctrl_info *ctrl_info, struct sc + timeout_msecs = reset_rc ? PQI_LUN_RESET_FAILED_PENDING_IO_TIMEOUT_MSECS : + PQI_LUN_RESET_PENDING_IO_TIMEOUT_MSECS; + +- wait_rc = pqi_device_wait_for_pending_io(ctrl_info, device, scmd->device->lun, timeout_msecs); ++ wait_rc = pqi_device_wait_for_pending_io(ctrl_info, device, lun, timeout_msecs); + if (wait_rc && reset_rc == 0) + reset_rc = wait_rc; + + return reset_rc == 0 ? SUCCESS : FAILED; + } + +-static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) ++static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun) + { + int rc; +- struct pqi_scsi_dev *device; + +- device = scmd->device->hostdata; + pqi_ctrl_block_requests(ctrl_info); + pqi_ctrl_wait_until_quiesced(ctrl_info); +- pqi_fail_io_queued_for_device(ctrl_info, device); ++ pqi_fail_io_queued_for_device(ctrl_info, device, lun); + rc = pqi_wait_until_inbound_queues_empty(ctrl_info); ++ pqi_device_reset_start(device, lun); ++ pqi_ctrl_unblock_requests(ctrl_info); + if (rc) + rc = FAILED; + else +- rc = pqi_lun_reset_with_retries(ctrl_info, scmd); +- pqi_ctrl_unblock_requests(ctrl_info); ++ rc = pqi_lun_reset_with_retries(ctrl_info, device, lun); ++ pqi_device_reset_done(device, lun); + + return rc; + } + +-static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) ++static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { + int rc; +- struct Scsi_Host *shost; +- struct pqi_ctrl_info *ctrl_info; +- struct pqi_scsi_dev *device; +- +- shost = scmd->device->host; +- ctrl_info = shost_to_hba(shost); +- device = scmd->device->hostdata; + + mutex_lock(&ctrl_info->lun_reset_mutex); + + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%d due to cmd 0x%02x\n", +- shost->host_no, +- device->bus, device->target, (u32)scmd->device->lun, ++ ctrl_info->scsi_host->host_no, ++ device->bus, device->target, lun, + scmd->cmd_len > 0 ? scmd->cmnd[0] : 0xff); + + pqi_check_ctrl_health(ctrl_info); + if (pqi_ctrl_offline(ctrl_info)) + rc = FAILED; + else +- rc = pqi_device_reset(ctrl_info, scmd); ++ rc = pqi_device_reset(ctrl_info, device, lun); + + dev_err(&ctrl_info->pci_dev->dev, +- "reset of scsi %d:%d:%d:%d: %s\n", +- shost->host_no, device->bus, device->target, (u32)scmd->device->lun, ++ "reset of scsi %d:%d:%d:%u: %s\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, lun, + rc == SUCCESS ? "SUCCESS" : "FAILED"); + + mutex_unlock(&ctrl_info->lun_reset_mutex); +@@ -6395,6 +6427,74 @@ static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) + return rc; + } + ++static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd) ++{ ++ struct Scsi_Host *shost; ++ struct pqi_ctrl_info *ctrl_info; ++ struct pqi_scsi_dev *device; ++ u8 scsi_opcode; ++ ++ shost = scmd->device->host; ++ ctrl_info = shost_to_hba(shost); ++ device = scmd->device->hostdata; ++ scsi_opcode = scmd->cmd_len > 0 ? scmd->cmnd[0] : 0xff; ++ ++ return pqi_device_reset_handler(ctrl_info, device, (u8)scmd->device->lun, scmd, scsi_opcode); ++} ++ ++static void pqi_tmf_worker(struct work_struct *work) ++{ ++ struct pqi_tmf_work *tmf_work; ++ struct scsi_cmnd *scmd; ++ ++ tmf_work = container_of(work, struct pqi_tmf_work, work_struct); ++ scmd = (struct scsi_cmnd *)xchg(&tmf_work->scmd, NULL); ++ ++ pqi_device_reset_handler(tmf_work->ctrl_info, tmf_work->device, tmf_work->lun, scmd, tmf_work->scsi_opcode); ++} ++ ++static int pqi_eh_abort_handler(struct scsi_cmnd *scmd) ++{ ++ struct Scsi_Host *shost; ++ struct pqi_ctrl_info *ctrl_info; ++ struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; ++ DECLARE_COMPLETION_ONSTACK(wait); ++ ++ shost = scmd->device->host; ++ ctrl_info = shost_to_hba(shost); ++ ++ dev_err(&ctrl_info->pci_dev->dev, ++ "attempting TASK ABORT on SCSI cmd at %p\n", scmd); ++ ++ if (cmpxchg(&scmd->host_scribble, PQI_NO_COMPLETION, (void *)&wait) == NULL) { ++ dev_err(&ctrl_info->pci_dev->dev, ++ "SCSI cmd at %p already completed\n", scmd); ++ scmd->result = DID_RESET << 16; ++ goto out; ++ } ++ ++ device = scmd->device->hostdata; ++ tmf_work = &device->tmf_work[scmd->device->lun]; ++ ++ if (cmpxchg(&tmf_work->scmd, NULL, scmd) == NULL) { ++ tmf_work->ctrl_info = ctrl_info; ++ tmf_work->device = device; ++ tmf_work->lun = (u8)scmd->device->lun; ++ tmf_work->scsi_opcode = scmd->cmd_len > 0 ? scmd->cmnd[0] : 0xff; ++ schedule_work(&tmf_work->work_struct); ++ } ++ ++ wait_for_completion(&wait); ++ ++ dev_err(&ctrl_info->pci_dev->dev, ++ "TASK ABORT on SCSI cmd at %p: SUCCESS\n", scmd); ++ ++out: ++ ++ return SUCCESS; ++} ++ + static int pqi_slave_alloc(struct scsi_device *sdev) + { + struct pqi_scsi_dev *device; +@@ -7398,6 +7498,7 @@ static struct scsi_host_template pqi_driver_template = { + .scan_finished = pqi_scan_finished, + .this_id = -1, + .eh_device_reset_handler = pqi_eh_device_reset_handler, ++ .eh_abort_handler = pqi_eh_abort_handler, + .ioctl = pqi_ioctl, + .slave_alloc = pqi_slave_alloc, + .slave_configure = pqi_slave_configure, +-- +2.51.0 + diff --git a/queue-6.1/scsi-smartpqi-convert-to-host_tagset.patch b/queue-6.1/scsi-smartpqi-convert-to-host_tagset.patch new file mode 100644 index 0000000000..f3ab85ff61 --- /dev/null +++ b/queue-6.1/scsi-smartpqi-convert-to-host_tagset.patch @@ -0,0 +1,202 @@ +From 6ae50a87fc58d56848e18f006a1d36cb89747c5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Nov 2022 13:21:38 -0600 +Subject: scsi: smartpqi: Convert to host_tagset + +From: Don Brace + +[ Upstream commit b27ac2faa2fc0b2677cf1cbd270af734a1f5fd95 ] + +Add support for host_tagset. + +Also move the reserved command slots to the end of the pool to eliminate an +addition operation for every SCSI request. + +This patch was originally authored by Hannes Reinecke here: + +Link: https://lore.kernel.org/linux-block/20191126131009.71726-8-hare@suse.de/ + +But we NAKed this patch because we wanted to fully test multipath +failover operations. + +Suggested-by: Hannes Reinecke +Reviewed-by: Scott Benesh +Reviewed-by: Scott Teel +Reviewed-by: Mahesh Rajashekhara +Reviewed-by: Mike McGowen +Reviewed-by: Kevin Barnett +Signed-off-by: Don Brace +Link: https://lore.kernel.org/r/166793529811.322537.3294617845448383948.stgit@brunhilda +Signed-off-by: Martin K. Petersen +Stable-dep-of: b518e86d1a70 ("scsi: smartpqi: Fix device resources accessed after device removal") +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi.h | 3 -- + drivers/scsi/smartpqi/smartpqi_init.c | 68 +++++++++++++++++---------- + 2 files changed, 43 insertions(+), 28 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index c8235f15728bb..af27bb0f3133e 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -1307,7 +1307,6 @@ struct pqi_ctrl_info { + dma_addr_t error_buffer_dma_handle; + size_t sg_chain_buffer_length; + unsigned int num_queue_groups; +- u16 max_hw_queue_index; + u16 num_elements_per_iq; + u16 num_elements_per_oq; + u16 max_inbound_iu_length_per_firmware; +@@ -1369,8 +1368,6 @@ struct pqi_ctrl_info { + u64 sas_address; + + struct pqi_io_request *io_request_pool; +- u16 next_io_request_slot; +- + struct pqi_event events[PQI_NUM_SUPPORTED_EVENTS]; + struct work_struct event_work; + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 0b3aa91b46ffb..d97946a09f646 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -678,23 +678,36 @@ static inline void pqi_reinit_io_request(struct pqi_io_request *io_request) + io_request->raid_bypass = false; + } + +-static struct pqi_io_request *pqi_alloc_io_request( +- struct pqi_ctrl_info *ctrl_info) ++static inline struct pqi_io_request *pqi_alloc_io_request(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd) + { + struct pqi_io_request *io_request; +- u16 i = ctrl_info->next_io_request_slot; /* benignly racy */ ++ u16 i; + +- while (1) { ++ if (scmd) { /* SML I/O request */ ++ u32 blk_tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd)); ++ ++ i = blk_mq_unique_tag_to_tag(blk_tag); + io_request = &ctrl_info->io_request_pool[i]; +- if (atomic_inc_return(&io_request->refcount) == 1) +- break; +- atomic_dec(&io_request->refcount); +- i = (i + 1) % ctrl_info->max_io_slots; ++ if (atomic_inc_return(&io_request->refcount) > 1) { ++ atomic_dec(&io_request->refcount); ++ return NULL; ++ } ++ } else { /* IOCTL or driver internal request */ ++ /* ++ * benignly racy - may have to wait for an open slot. ++ * command slot range is scsi_ml_can_queue - ++ * [scsi_ml_can_queue + (PQI_RESERVED_IO_SLOTS - 1)] ++ */ ++ i = 0; ++ while (1) { ++ io_request = &ctrl_info->io_request_pool[ctrl_info->scsi_ml_can_queue + i]; ++ if (atomic_inc_return(&io_request->refcount) == 1) ++ break; ++ atomic_dec(&io_request->refcount); ++ i = (i + 1) % PQI_RESERVED_IO_SLOTS; ++ } + } + +- /* benignly racy */ +- ctrl_info->next_io_request_slot = (i + 1) % ctrl_info->max_io_slots; +- + pqi_reinit_io_request(io_request); + + return io_request; +@@ -4579,7 +4592,7 @@ static int pqi_submit_raid_request_synchronous(struct pqi_ctrl_info *ctrl_info, + goto out; + } + +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, NULL); + + put_unaligned_le16(io_request->index, + &(((struct pqi_raid_path_request *)request)->request_id)); +@@ -5226,7 +5239,6 @@ static void pqi_calculate_queue_resources(struct pqi_ctrl_info *ctrl_info) + } + + ctrl_info->num_queue_groups = num_queue_groups; +- ctrl_info->max_hw_queue_index = num_queue_groups - 1; + + /* + * Make sure that the max. inbound IU length is an even multiple +@@ -5560,7 +5572,9 @@ static inline int pqi_raid_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info, + { + struct pqi_io_request *io_request; + +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, scmd); ++ if (!io_request) ++ return SCSI_MLQUEUE_HOST_BUSY; + + return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request, + device, scmd, queue_group); +@@ -5664,7 +5678,9 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info, + struct pqi_scsi_dev *device; + + device = scmd->device->hostdata; +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, scmd); ++ if (!io_request) ++ return SCSI_MLQUEUE_HOST_BUSY; + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = raid_bypass; +@@ -5736,7 +5752,10 @@ static int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info, + struct pqi_io_request *io_request; + struct pqi_aio_r1_path_request *r1_request; + +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, scmd); ++ if (!io_request) ++ return SCSI_MLQUEUE_HOST_BUSY; ++ + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; +@@ -5794,7 +5813,9 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + struct pqi_io_request *io_request; + struct pqi_aio_r56_path_request *r56_request; + +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, scmd); ++ if (!io_request) ++ return SCSI_MLQUEUE_HOST_BUSY; + io_request->io_complete_callback = pqi_aio_io_complete; + io_request->scmd = scmd; + io_request->raid_bypass = true; +@@ -5853,13 +5874,10 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, + static inline u16 pqi_get_hw_queue(struct pqi_ctrl_info *ctrl_info, + struct scsi_cmnd *scmd) + { +- u16 hw_queue; +- +- hw_queue = blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scsi_cmd_to_rq(scmd))); +- if (hw_queue > ctrl_info->max_hw_queue_index) +- hw_queue = 0; +- +- return hw_queue; ++ /* ++ * We are setting host_tagset = 1 during init. ++ */ ++ return blk_mq_unique_tag_to_hwq(blk_mq_unique_tag(scsi_cmd_to_rq(scmd))); + } + + static inline bool pqi_is_bypass_eligible_request(struct scsi_cmnd *scmd) +@@ -6261,7 +6279,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd + struct pqi_scsi_dev *device; + + device = scmd->device->hostdata; +- io_request = pqi_alloc_io_request(ctrl_info); ++ io_request = pqi_alloc_io_request(ctrl_info, NULL); + io_request->io_complete_callback = pqi_lun_reset_complete; + io_request->context = &wait; + +-- +2.51.0 + diff --git a/queue-6.1/scsi-smartpqi-fix-device-resources-accessed-after-de.patch b/queue-6.1/scsi-smartpqi-fix-device-resources-accessed-after-de.patch new file mode 100644 index 0000000000..1d446bf6b0 --- /dev/null +++ b/queue-6.1/scsi-smartpqi-fix-device-resources-accessed-after-de.patch @@ -0,0 +1,94 @@ +From c2d04e7c2ab652c707917a7447bd62f3b0897640 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 10:38:20 -0600 +Subject: scsi: smartpqi: Fix device resources accessed after device removal + +From: Mike McGowen + +[ Upstream commit b518e86d1a70a88f6592a7c396cf1b93493d1aab ] + +Correct possible race conditions during device removal. + +Previously, a scheduled work item to reset a LUN could still execute +after the device was removed, leading to use-after-free and other +resource access issues. + +This race condition occurs because the abort handler may schedule a LUN +reset concurrently with device removal via sdev_destroy(), leading to +use-after-free and improper access to freed resources. + + - Check in the device reset handler if the device is still present in + the controller's SCSI device list before running; if not, the reset + is skipped. + + - Cancel any pending TMF work that has not started in sdev_destroy(). + + - Ensure device freeing in sdev_destroy() is done while holding the + LUN reset mutex to avoid races with ongoing resets. + +Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 5e39df2b6a4c0..a9f504959dd56 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6401,10 +6401,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev + + static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { ++ unsigned long flags; + int rc; + + mutex_lock(&ctrl_info->lun_reset_mutex); + ++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); ++ if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { ++ dev_warn(&ctrl_info->pci_dev->dev, ++ "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%d due to cmd 0x%02x\n", + ctrl_info->scsi_host->host_no, +@@ -6583,7 +6595,9 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + { + struct pqi_ctrl_info *ctrl_info; + struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; + int mutex_acquired; ++ unsigned int lun; + unsigned long flags; + + ctrl_info = shost_to_hba(sdev->host); +@@ -6610,8 +6624,13 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + + mutex_unlock(&ctrl_info->scan_mutex); + ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ cancel_work_sync(&tmf_work->work_struct); ++ ++ mutex_lock(&ctrl_info->lun_reset_mutex); + pqi_dev_info(ctrl_info, "removed", device); + pqi_free_device(device); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); + } + + static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) +-- +2.51.0 + diff --git a/queue-6.1/scsi-smartpqi-remove-contention-for-raid_bypass_cnt.patch b/queue-6.1/scsi-smartpqi-remove-contention-for-raid_bypass_cnt.patch new file mode 100644 index 0000000000..e2bb7b07c1 --- /dev/null +++ b/queue-6.1/scsi-smartpqi-remove-contention-for-raid_bypass_cnt.patch @@ -0,0 +1,76 @@ +From 268bce63c778deb3cd7c812c95a1f9e07ab0969b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Apr 2023 10:37:05 -0500 +Subject: scsi: smartpqi: Remove contention for raid_bypass_cnt + +From: Mike McGowen + +[ Upstream commit 80d560d94fa9b28069c62e1a64ae4a03d5f43fbc ] + +Reduce CPU contention when incrementing variable raid_bypass_cnt. + +Remove the atomic operations for this variable by changing the atomic to an +unsigned int and replace atomic operations with standard operations. The +value is only checked that it is increasing and accuracy is not required. + +Reviewed-by: Scott Benesh +Reviewed-by: Scott Teel +Reviewed-by: Kevin Barnett +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://lore.kernel.org/r/20230428153712.297638-6-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Stable-dep-of: b518e86d1a70 ("scsi: smartpqi: Fix device resources accessed after device removal") +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi.h | 2 +- + drivers/scsi/smartpqi/smartpqi_init.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h +index af27bb0f3133e..6e2f08ac68166 100644 +--- a/drivers/scsi/smartpqi/smartpqi.h ++++ b/drivers/scsi/smartpqi/smartpqi.h +@@ -1147,7 +1147,7 @@ struct pqi_scsi_dev { + + struct pqi_stream_data stream_data[NUM_STREAMS_PER_LUN]; + atomic_t scsi_cmds_outstanding[PQI_MAX_LUNS_PER_DEVICE]; +- atomic_t raid_bypass_cnt; ++ unsigned int raid_bypass_cnt; + }; + + /* VPD inquiry pages */ +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index d97946a09f646..4822b830ea371 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6035,7 +6035,7 @@ static int pqi_scsi_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scm + rc = pqi_raid_bypass_submit_scsi_cmd(ctrl_info, device, scmd, queue_group); + if (rc == 0 || rc == SCSI_MLQUEUE_HOST_BUSY) { + raid_bypassed = true; +- atomic_inc(&device->raid_bypass_cnt); ++ device->raid_bypass_cnt++; + } + } + if (!raid_bypassed) +@@ -7274,7 +7274,7 @@ static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, + struct scsi_device *sdev; + struct pqi_scsi_dev *device; + unsigned long flags; +- int raid_bypass_cnt; ++ unsigned int raid_bypass_cnt; + + sdev = to_scsi_device(dev); + ctrl_info = shost_to_hba(sdev->host); +@@ -7290,7 +7290,7 @@ static ssize_t pqi_raid_bypass_cnt_show(struct device *dev, + return -ENODEV; + } + +- raid_bypass_cnt = atomic_read(&device->raid_bypass_cnt); ++ raid_bypass_cnt = device->raid_bypass_cnt; + + spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); + +-- +2.51.0 + diff --git a/queue-6.1/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-6.1/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..9713b78912 --- /dev/null +++ b/queue-6.1/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From 4a44320301fdb41c7e8ee66b39ef04f72557bd41 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index 6b07f367918ef..56b29b52fce71 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1846,6 +1846,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-6.1/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-6.1/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..126ef71830 --- /dev/null +++ b/queue-6.1/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From 2e85e885a920c43246b626d6eca96942836abb7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 537c1370e112a..e38f8343b75cc 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2689,7 +2689,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-6.1/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch b/queue-6.1/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch new file mode 100644 index 0000000000..debf82ec2a --- /dev/null +++ b/queue-6.1/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch @@ -0,0 +1,46 @@ +From ff73b96fce8b86ec100a05ac3b183b7175603a13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 00:05:17 +0100 +Subject: scsi: ufs: core: fix incorrect buffer duplication in + ufshcd_read_string_desc() + +From: Bean Huo + +[ Upstream commit d794b499f948801f54d67ddbc34a6eac5a6d150a ] + +The function ufshcd_read_string_desc() was duplicating memory starting +from the beginning of struct uc_string_id, which included the length and +type fields. As a result, the allocated buffer contained unwanted +metadata in addition to the string itself. + +The correct behavior is to duplicate only the Unicode character array in +the structure. Update the code so that only the actual string content is +copied into the new buffer. + +Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Bean Huo +Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 1120e83f781eb..7f24563159c1f 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3586,7 +3586,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + str[ret++] = '\0'; + + } else { +- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); ++ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + goto out; +-- +2.51.0 + diff --git a/queue-6.1/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-6.1/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..0a81b41462 --- /dev/null +++ b/queue-6.1/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From db4f19596be11bbee5bcd6db1a4bba0c7f6d1b5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 8a8a5cf8d8e65..090a2fadf4bb3 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1552,8 +1552,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5105,9 +5103,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Triggered when there are no references on the socket anymore */ +-- +2.51.0 + diff --git a/queue-6.1/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-6.1/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..1ed533a80c --- /dev/null +++ b/queue-6.1/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 0851da0e6b6dabe5d9073f767290debe77b8ce91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 210b806351bcf..08cc9b06feceb 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -141,6 +141,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-6.1/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-6.1/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..5d1c596fc3 --- /dev/null +++ b/queue-6.1/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 47034b97e8ae5c627442360397ba6f97be382986 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 06c7986131d96..0a7ef770c487c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-6.1/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-6.1/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..9b06ae9860 --- /dev/null +++ b/queue-6.1/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From 72a20b214851283eb1b3bc9aec0cc8ef5684b870 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index bc24f83339d64..06c7986131d96 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index e6fbc3bafd..b4576f9145 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -38,3 +38,149 @@ comedi-check-device-s-attached-status-in-compat-ioctls.patch staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_ie-parser.patch staging-rtl8723bs-fix-stack-buffer-overflow-in-onassocreq-ie-parsing.patch staging-rtl8723bs-fix-out-of-bounds-read-in-onbeacon-esr-ie-parsing.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch +objtool-fix-find_-symbol-func-_containing.patch +objtool-fix-weak-symbol-detection.patch +irqchip-irq-bcm7038-l1-fix-section-mismatch.patch +irqchip-irq-bcm7120-l2-fix-section-mismatch.patch +irqchip-irq-brcmstb-l2-fix-section-mismatch.patch +irqchip-imx-mu-msi-fix-section-mismatch.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +wifi-ath11k-fix-peer-he-mcs-assignment.patch +s390-smp-fix-fallback-cpu-detection.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch +soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +i3c-allow-of-alias-based-persistent-bus-numbering.patch +i3c-master-inherit-dma-masks-and-parameters-from-par.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +interconnect-qcom-msm8996-add-missing-link-to-slave_.patch +perf-record-skip-synthesize-event-when-open-evsel-fa.patch +power-supply-cw2015-check-devm_delayed_work_autocanc.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +spi-tegra210-quad-fix-timeout-handling.patch +x86-boot-fix-page-table-access-in-5-level-to-4-level.patch +efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +scsi-smartpqi-convert-to-host_tagset.patch +scsi-smartpqi-remove-contention-for-raid_bypass_cnt.patch +scsi-smartpqi-add-abort-handler.patch +scsi-smartpqi-fix-device-resources-accessed-after-de.patch +dt-bindings-pci-convert-amlogic-meson-pcie.txt-to-dt.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +ntfs3-init-run-lock-for-extend-inode.patch +scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +coresight-etm4x-correct-polling-idle-bit.patch +coresight-etm4x-extract-the-trace-unit-controlling.patch +coresight-etm4x-add-context-synchronization-before-e.patch +soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +bpf-improve-program-stats-run-time-calculation.patch +bpf-fix-invalid-prog-stats-access-when-update_effect.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch +net-phy-adin1100-fix-software-power-down-ready-condi.patch +cpuset-treat-cpusets-in-attaching-as-populated.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led_bl-take-led_access-lock-when-required.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +asoc-fsl_xcvr-add-counter-registers.patch +asoc-fsl_xcvr-add-support-for-i.mx93-platform.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ext4-remove-unused-return-value-of-__mb_check_buddy.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-typo-in-virtio_device_ready-comment.patch +virtio-fix-virtqueue_set_affinity-docs.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +resource-replace-printk-kern_warning-by-pr_warn-prin.patch +resource-reuse-for_each_resource-macro.patch +resource-replace-open-coded-resource_intersection.patch +resource-introduce-is_type_match-helper-and-use-it.patch +reinstate-resource-avoid-unnecessary-lookups-in-find.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +md-export-md_is_rdwr-and-is_md_suspended.patch +md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +pinctrl-single-fix-pin_config_bias_disable-handling.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch diff --git a/queue-6.1/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-6.1/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..389440bd93 --- /dev/null +++ b/queue-6.1/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From dd8a317be244b75eabb18ad5bdb018a576cf69e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 285103ffc75c6..4b252646081b4 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3624,8 +3624,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3636,28 +3636,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + if (strcmp(name, "current") != 0) + return -EINVAL; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.1/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.1/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..0bfb7cda2c --- /dev/null +++ b/queue-6.1/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,51 @@ +From 8d614bcb239445ae9c0a277269cc616097c28278 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:27:33 +0800 +Subject: soc: qcom: smem: fix hwspinlock resource leak in probe error paths + +From: Haotian Zhang + +[ Upstream commit dc5db35073a19f6d3c30bea367b551c1a784ef8f ] + +The hwspinlock acquired via hwspin_lock_request_specific() is not +released on several error paths. This results in resource leakage +when probe fails. + +Switch to devm_hwspin_lock_request_specific() to automatically +handle cleanup on probe failure. Remove the manual hwspin_lock_free() +in qcom_smem_remove() as devm handles it automatically. + +Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/smem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index e4e6c6d69bf55..06958de43f8ca 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1105,7 +1105,7 @@ static int qcom_smem_probe(struct platform_device *pdev) + return hwlock_id; + } + +- smem->hwlock = hwspin_lock_request_specific(hwlock_id); ++ smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); + if (!smem->hwlock) + return -ENXIO; + +@@ -1158,7 +1158,6 @@ static int qcom_smem_remove(struct platform_device *pdev) + { + platform_device_unregister(__smem->socinfo); + +- hwspin_lock_free(__smem->hwlock); + __smem = NULL; + + return 0; +-- +2.51.0 + diff --git a/queue-6.1/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch b/queue-6.1/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch new file mode 100644 index 0000000000..3972e7afdd --- /dev/null +++ b/queue-6.1/soc-renesas-r9a06g032-sysctrl-handle-h2mode-setting-.patch @@ -0,0 +1,85 @@ +From 51903ef3259730bfe80f74031cfcae1bf97fa6e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 5 Jan 2023 16:22:54 +0100 +Subject: soc: renesas: r9a06g032-sysctrl: Handle h2mode setting based on USBF + presence + +From: Herve Codina + +[ Upstream commit e9fee814b054e4f6f2faf3d9c1944869fe41c9dd ] + +The CFG_USB[H2MODE] allows to switch the USB configuration. The +configuration supported are: + - One host and one device +or + - Two hosts + +Set CFG_USB[H2MODE] based on the USBF controller (USB device) +availability. + +Signed-off-by: Herve Codina +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230105152257.310642-3-herve.codina@bootlin.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: f8def051bbcf ("clk: renesas: r9a06g032: Fix memory leak in error path") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 28 ++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 983faa5707b9c..087146f2ee068 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -25,6 +25,8 @@ + #include + #include + ++#define R9A06G032_SYSCTRL_USB 0x00 ++#define R9A06G032_SYSCTRL_USB_H2MODE (1<<1) + #define R9A06G032_SYSCTRL_DMAMUX 0xA0 + + struct r9a06g032_gate { +@@ -918,6 +920,29 @@ static void r9a06g032_clocks_del_clk_provider(void *data) + of_clk_del_provider(data); + } + ++static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks) ++{ ++ struct device_node *usbf_np = NULL; ++ u32 usb; ++ ++ while ((usbf_np = of_find_compatible_node(usbf_np, NULL, ++ "renesas,rzn1-usbf"))) { ++ if (of_device_is_available(usbf_np)) ++ break; ++ } ++ ++ usb = readl(clocks->reg + R9A06G032_SYSCTRL_USB); ++ if (usbf_np) { ++ /* 1 host and 1 device mode */ ++ usb &= ~R9A06G032_SYSCTRL_USB_H2MODE; ++ of_node_put(usbf_np); ++ } else { ++ /* 2 hosts mode */ ++ usb |= R9A06G032_SYSCTRL_USB_H2MODE; ++ } ++ writel(usb, clocks->reg + R9A06G032_SYSCTRL_USB); ++} ++ + static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + { + struct device *dev = &pdev->dev; +@@ -947,6 +972,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + clocks->reg = of_iomap(np, 0); + if (WARN_ON(!clocks->reg)) + return -ENOMEM; ++ ++ r9a06g032_init_h2mode(clocks); ++ + for (i = 0; i < ARRAY_SIZE(r9a06g032_clocks); ++i) { + const struct r9a06g032_clkdesc *d = &r9a06g032_clocks[i]; + const char *parent_name = d->source ? +-- +2.51.0 + diff --git a/queue-6.1/spi-tegra210-quad-fix-timeout-handling.patch b/queue-6.1/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..4e977517e9 --- /dev/null +++ b/queue-6.1/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,117 @@ +From 65e8dd5eccbf7d83fa4ef99d930674343fea7449 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index f2a4743efcb47..2e4d1b2f2a273 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -998,8 +998,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1138,9 +1140,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1162,11 +1166,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + ret = 0; + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1248,6 +1254,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1344,6 +1352,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1427,6 +1436,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-6.1/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-6.1/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..69f5133a80 --- /dev/null +++ b/queue-6.1/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From f930382f4ac69d7e2edee8f83608b5478cabf90d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 7b802b0226273..c20e1afc0ada2 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1225,8 +1225,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-6.1/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch b/queue-6.1/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch new file mode 100644 index 0000000000..1caec79d3c --- /dev/null +++ b/queue-6.1/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch @@ -0,0 +1,43 @@ +From b49d81e4b2e15ca3f83e0107673718241b6f4ca3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:50 +0200 +Subject: tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit c485ca3aff2442adea4c08ceb5183e671ebed22a ] + +There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, +simply print the message with "unknown error" rather than the integer +value of errno. + +Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/stdio.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h +index 96ac8afc5aeed..64dcdfbbe3d9c 100644 +--- a/tools/include/nolibc/stdio.h ++++ b/tools/include/nolibc/stdio.h +@@ -300,7 +300,11 @@ int printf(const char *fmt, ...) + static __attribute__((unused)) + void perror(const char *msg) + { ++#ifdef NOLIBC_IGNORE_ERRNO ++ fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); ++#else + fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); ++#endif + } + + /* make sure to include all global symbols */ +-- +2.51.0 + diff --git a/queue-6.1/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-6.1/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..f20f5d861d --- /dev/null +++ b/queue-6.1/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From 82e7210c37f224a4668eed4a53e854069edba6a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 7d8eb9dc20681..db4e64550f121 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-6.1/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-6.1/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..489bfe4954 --- /dev/null +++ b/queue-6.1/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From dbf7ef2b1fea933a6cee59b091fe83f85ed10662 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index d99d424c05a7a..50909cc9a0bb2 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -445,9 +445,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-6.1/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch b/queue-6.1/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch new file mode 100644 index 0000000000..1223a1b36f --- /dev/null +++ b/queue-6.1/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch @@ -0,0 +1,45 @@ +From d85f7617c40a9eb30da256c0470ca3e0b01bf703 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Jun 2025 17:46:55 +0800 +Subject: usb: dwc2: disable platform lowlevel hw resources during shutdown + +From: Jisheng Zhang + +[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ] + +On some SoC platforms, in shutdown stage, most components' power is cut +off, but there's still power supply to the so called always-on +domain, so if the dwc2's regulator is from the always-on domain, we +need to explicitly disable it to save power. + +Disable platform lowlevel hw resources such as phy, clock and +regulators etc. in device shutdown hook to reduce non-necessary power +consumption when the platform enters shutdown stage. + +Signed-off-by: Jisheng Zhang +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 9de5a1be4a0ae..5e8c74e20bffa 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -340,6 +340,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); ++ ++ if (hsotg->ll_hw_enabled) ++ dwc2_lowlevel_hw_disable(hsotg); + } + + /** +-- +2.51.0 + diff --git a/queue-6.1/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-6.1/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..4cbaef8336 --- /dev/null +++ b/queue-6.1/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From e2ab6b44ee2f072d3515b6b60d6e3fdbcefd9dc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 5e8c74e20bffa..8e80b20361e3a 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -338,11 +338,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-6.1/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-6.1/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..19bef41771 --- /dev/null +++ b/queue-6.1/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From f28aaeb190504539b8b0cadefca3160da991ec1d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 8e80b20361e3a..4464c7b1f0cf1 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -618,9 +618,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -671,6 +675,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-6.1/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-6.1/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..9338e13528 --- /dev/null +++ b/queue-6.1/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From 2c89090b375635d0a914d5bb3c8c6723b2489540 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index 1673e5d089263..9f65556dc3745 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2386,7 +2386,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-6.1/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-6.1/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..5a892ee1d3 --- /dev/null +++ b/queue-6.1/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 96611e866a3e255815ae72260e44ca17f57eafc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index 2deab4a6030d7..8aa1a8408ae33 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -39,6 +39,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -620,6 +621,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-6.1/virtio-fix-typo-in-virtio_device_ready-comment.patch b/queue-6.1/virtio-fix-typo-in-virtio_device_ready-comment.patch new file mode 100644 index 0000000000..9322057f43 --- /dev/null +++ b/queue-6.1/virtio-fix-typo-in-virtio_device_ready-comment.patch @@ -0,0 +1,36 @@ +From 3c6bc6688e289e1526f504e06ba831bb8046eaba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:31 -0500 +Subject: virtio: fix typo in virtio_device_ready() comment + +From: Michael S. Tsirkin + +[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ] + +"coherenct" -> "coherent" + +Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 4b517649cfe84..eee145cfea6b5 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -286,7 +286,7 @@ void virtio_device_ready(struct virtio_device *dev) + * specific set_status() method. + * + * A well behaved device will only notify a virtqueue after +- * DRIVER_OK, this means the device should "see" the coherenct ++ * DRIVER_OK, this means the device should "see" the coherent + * memory write that set vq->broken as false which is done by + * the driver when it sees DRIVER_OK, then the following + * driver's vring_interrupt() will see vq->broken as false so +-- +2.51.0 + diff --git a/queue-6.1/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-6.1/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..e7b44c17b0 --- /dev/null +++ b/queue-6.1/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From 19ef90114dbeb15d6d570919e95c489efe821777 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index eee145cfea6b5..2051295c3920c 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -308,7 +308,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu_mask: the cpu mask + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-6.1/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-6.1/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..08c8253a6c --- /dev/null +++ b/queue-6.1/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From f66ed1e907e282a332b14ad19691ebc6f68d6b93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index 056ba6c5bb083..0d596609e1571 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -92,7 +92,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-6.1/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-6.1/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..3fb18ac351 --- /dev/null +++ b/queue-6.1/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From 7d3f231dae3fc5b6132841bf383ae97dcaeb9c47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index ce7a4a9e4b03c..4bc56c49147c7 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -327,19 +327,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); +@@ -356,15 +364,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -386,8 +399,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -418,7 +433,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -426,8 +442,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -441,7 +459,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -458,12 +476,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + static int wdat_wdt_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.1/wifi-ath11k-fix-peer-he-mcs-assignment.patch b/queue-6.1/wifi-ath11k-fix-peer-he-mcs-assignment.patch new file mode 100644 index 0000000000..b205d05523 --- /dev/null +++ b/queue-6.1/wifi-ath11k-fix-peer-he-mcs-assignment.patch @@ -0,0 +1,94 @@ +From 100fc08c26b138d8fd4a68d4c50b199ab044841f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:49:00 +0800 +Subject: wifi: ath11k: fix peer HE MCS assignment + +From: Baochen Qiang + +[ Upstream commit 4a013ca2d490c73c40588d62712ffaa432046a04 ] + +In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to +firmware as receive MCS while peer's receive MCS sent as transmit MCS, +which goes against firmwire's definition. + +While connecting to a misbehaved AP that advertises 0xffff (meaning not +supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff +is assigned to he_mcs->rx_mcs_set field. + + Ext Tag: HE Capabilities + [...] + Supported HE-MCS and NSS Set + [...] + Rx and Tx MCS Maps 160 MHz + [...] + Tx HE-MCS Map 160 MHz: 0xffff + +Swap the assignment to fix this issue. + +As the HE rate control mask is meant to limit our own transmit MCS, it +needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive MCS. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 4cab480f85a8d..6a244f110dca6 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2243,10 +2243,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2256,10 +2256,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index ed12bbb11fe89..8b50dbc47300b 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -2013,8 +2013,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ /* firmware interprets mcs->rx_mcs_set field as peer's ++ * RX capability ++ */ ++ he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +-- +2.51.0 + diff --git a/queue-6.1/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-6.1/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..81ea9df295 --- /dev/null +++ b/queue-6.1/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From a3b8245f210ac6ec908e68489b245d1628d4e592 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 3b4ded2ac801c..37232ee220375 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-6.1/wifi-ieee80211-correct-fils-status-codes.patch b/queue-6.1/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..ca6552adff --- /dev/null +++ b/queue-6.1/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From 5a4f177307fe51f6e794150210376b13fc3f6c5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 8e00918b15b49..c16e90c5588ee 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3157,8 +3157,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + }; +-- +2.51.0 + diff --git a/queue-6.1/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-6.1/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..19e72e825d --- /dev/null +++ b/queue-6.1/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From d6ae56dbe0527acade6699a549de1ad93ce1366f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index cdfe08078c575..e975698545a56 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-6.1/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-6.1/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..e8567bd486 --- /dev/null +++ b/queue-6.1/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From 05670fc89601e9be87aa00687d5eecdce6f49323 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index fa3fb93f4485d..fd67c11bbf618 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-6.1/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch b/queue-6.1/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch new file mode 100644 index 0000000000..69999c489b --- /dev/null +++ b/queue-6.1/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch @@ -0,0 +1,87 @@ +From 91e5062f78047e941a105b64f1d404a173259a88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:22 +0000 +Subject: x86/boot: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit eb2266312507d7b757859e2227aa5c4ba6280ebe ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags. Bits above the + physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The PGD entry is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Acked-by: Dave Hansen +Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index 51f957b24ba7a..2355fab36af61 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -1,6 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + #include "misc.h" + #include ++#include + #include + #include "pgtable.h" + #include "../string.h" +@@ -173,9 +174,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * For 4- to 5-level paging transition, set up current CR3 as + * the first and the only entry in a new top-level page table. + */ +- *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; ++ *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; + } else { +- unsigned long src; ++ u64 *new_cr3; ++ pgd_t *pgdp; + + /* + * For 5- to 4-level paging transition, copy page table pointed +@@ -185,8 +187,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * We cannot just point to the page table from trampoline as it + * may be above 4G. + */ +- src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; +- memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); ++ pgdp = (pgd_t *)native_read_cr3_pa(); ++ new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); ++ memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); + } + + toggle_la57(trampoline_32bit); +-- +2.51.0 + diff --git a/queue-6.1/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-6.1/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..b10e58a1b1 --- /dev/null +++ b/queue-6.1/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From f44bcbf9114db8aeddbfc3708f64cff75c83d3b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 52dc5839d1e8e..0667d947d82bb 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,8 +183,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -305,6 +305,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-6.12/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch b/queue-6.12/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch new file mode 100644 index 0000000000..103a83ed5d --- /dev/null +++ b/queue-6.12/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch @@ -0,0 +1,60 @@ +From 1ae4e51655ea23eb4a0a4818a4db6d2e7b644931 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 16:30:53 -0600 +Subject: 9p: fix cache/debug options printing in v9fs_show_options + +From: Eric Sandeen + +[ Upstream commit f0445613314f474c1a0ec6fa8a5cd153a618f1b6 ] + +commit 4eb3117888a92 changed the cache= option to accept either string +shortcuts or bitfield values. It also changed /proc/mounts to emit the +option as the hexadecimal numeric value rather than the shortcut string. + +However, by printing "cache=%x" without the leading 0x, shortcuts such +as "cache=loose" will emit "cache=f" and 'f' is not a string that is +parseable by kstrtoint(), so remounting may fail if a remount with +"cache=f" is attempted. + +debug=%x has had the same problem since options have been displayed in +c4fac9100456 ("9p: Implement show_options") + +Fix these by adding the 0x prefix to the hexadecimal value shown in +/proc/mounts. + +Fixes: 4eb3117888a92 ("fs/9p: Rework cache modes and add new options to Documentation") +Signed-off-by: Eric Sandeen +Message-ID: <54b93378-dcf1-4b04-922d-c8b4393da299@redhat.com> +[Dominique: use %#x at Al Viro's suggestion, also handle debug] +Tested-by: Remi Pommarel +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/v9fs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c +index ccf00a948146a..bc879d32cfcf5 100644 +--- a/fs/9p/v9fs.c ++++ b/fs/9p/v9fs.c +@@ -101,7 +101,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; + + if (v9ses->debug) +- seq_printf(m, ",debug=%x", v9ses->debug); ++ seq_printf(m, ",debug=%#x", v9ses->debug); + if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) + seq_printf(m, ",dfltuid=%u", + from_kuid_munged(&init_user_ns, v9ses->dfltuid)); +@@ -117,7 +117,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + if (v9ses->nodev) + seq_puts(m, ",nodevmap"); + if (v9ses->cache) +- seq_printf(m, ",cache=%x", v9ses->cache); ++ seq_printf(m, ",cache=%#x", v9ses->cache); + #ifdef CONFIG_9P_FSCACHE + if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE)) + seq_printf(m, ",cachetag=%s", v9ses->cachetag); +-- +2.51.0 + diff --git a/queue-6.12/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch b/queue-6.12/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch new file mode 100644 index 0000000000..525a5c6ea1 --- /dev/null +++ b/queue-6.12/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch @@ -0,0 +1,51 @@ +From f8634ba90c4ef0fa65afc2d39c88b2ce45ed3bd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 10:48:09 +0200 +Subject: accel/ivpu: Ensure rpm_runtime_put in case of engine reset/resume + fail + +From: Karol Wachowski + +[ Upstream commit 9f6c63285737b141ca25a619add80a96111b8b96 ] + +Previously, aborting work could return early after engine reset or resume +failure, skipping the necessary runtime_put cleanup leaving the device +with incorrect reference count breaking runtime power management state. + +Replace early returns with goto statements to ensure runtime_put is always +executed. + +Fixes: a47e36dc5d90 ("accel/ivpu: Trigger device recovery on engine reset/resume failure") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250916084809.850073-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_job.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index a0dca1c253b74..172502b71b9cf 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -854,7 +854,7 @@ void ivpu_context_abort_thread_handler(struct work_struct *work) + + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (ivpu_jsm_reset_engine(vdev, 0)) +- return; ++ goto runtime_put; + + mutex_lock(&vdev->context_list_lock); + xa_for_each(&vdev->context_xa, ctx_id, file_priv) { +@@ -871,7 +871,7 @@ void ivpu_context_abort_thread_handler(struct work_struct *work) + goto runtime_put; + + if (ivpu_jsm_hws_resume_engine(vdev, 0)) +- return; ++ goto runtime_put; + /* + * In hardware scheduling mode NPU already has stopped processing jobs + * and won't send us any further notifications, thus we have to free job related resources +-- +2.51.0 + diff --git a/queue-6.12/accel-ivpu-fix-dct-active-percent-format.patch b/queue-6.12/accel-ivpu-fix-dct-active-percent-format.patch new file mode 100644 index 0000000000..b42c735808 --- /dev/null +++ b/queue-6.12/accel-ivpu-fix-dct-active-percent-format.patch @@ -0,0 +1,71 @@ +From 11c74ff0252619b36995f368ff53f149f7aa8008 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:43:22 +0200 +Subject: accel/ivpu: Fix DCT active percent format + +From: Karol Wachowski + +[ Upstream commit aa1c2b073ad23847dd2e7bdc7d30009f34ed7f59 ] + +The pcode MAILBOX STATUS register PARAM2 field expects DCT active +percent in U1.7 value format. Convert percentage value to this +format before writing to the register. + +Fixes: a19bffb10c46 ("accel/ivpu: Implement DCT handling") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20251001104322.1249896-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + drivers/accel/ivpu/ivpu_pm.c | 9 +++++++-- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c +index 2d88357b9a3a4..4af1b164d85a7 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.c ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c +@@ -759,7 +759,7 @@ int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable) + } + } + +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent) ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent) + { + u32 val = 0; + u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE; +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 7650f15b7ffa4..ac0cf50f004ff 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -35,7 +35,7 @@ u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev); + bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); + bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); + int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent); + u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); +diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c +index ad02b71c73bbf..bd8adba5ba70c 100644 +--- a/drivers/accel/ivpu/ivpu_pm.c ++++ b/drivers/accel/ivpu/ivpu_pm.c +@@ -466,6 +466,11 @@ void ivpu_pm_dct_irq_thread_handler(struct ivpu_device *vdev) + else + ret = ivpu_pm_dct_disable(vdev); + +- if (!ret) +- ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent); ++ if (!ret) { ++ /* Convert percent to U1.7 format */ ++ u8 val = DIV_ROUND_CLOSEST(vdev->pm->dct_active_percent * 128, 100); ++ ++ ivpu_hw_btrs_dct_set_status(vdev, enable, val); ++ } ++ + } +-- +2.51.0 + diff --git a/queue-6.12/accel-ivpu-make-function-parameter-names-consistent.patch b/queue-6.12/accel-ivpu-make-function-parameter-names-consistent.patch new file mode 100644 index 0000000000..d390683f4f --- /dev/null +++ b/queue-6.12/accel-ivpu-make-function-parameter-names-consistent.patch @@ -0,0 +1,51 @@ +From b3a8eafc2c148facbabf2679e74c6609881ab14e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Aug 2025 13:10:14 +0200 +Subject: accel/ivpu: Make function parameter names consistent + +From: Jacek Lawrynowicz + +[ Upstream commit cf87f93847dea607e8a35983cb006ef8493f8065 ] + +Make ivpu_hw_btrs_dct_set_status() and ivpu_fw_boot_params_setup() +declaration and definition parameter names consistent. + +Reviewed-by: Lizhi Hou +Signed-off-by: Jacek Lawrynowicz +Link: https://lore.kernel.org/r/20250808111014.328607-1-jacek.lawrynowicz@linux.intel.com +Stable-dep-of: aa1c2b073ad2 ("accel/ivpu: Fix DCT active percent format") +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_fw.h | 2 +- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h +index 1d0b2bd9d65cf..e6a1a1d0960c7 100644 +--- a/drivers/accel/ivpu/ivpu_fw.h ++++ b/drivers/accel/ivpu/ivpu_fw.h +@@ -44,7 +44,7 @@ struct ivpu_fw_info { + int ivpu_fw_init(struct ivpu_device *vdev); + void ivpu_fw_fini(struct ivpu_device *vdev); + void ivpu_fw_load(struct ivpu_device *vdev); +-void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *bp); ++void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params); + + static inline bool ivpu_fw_is_cold_boot(struct ivpu_device *vdev) + { +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 3855e2df1e0c8..7650f15b7ffa4 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -35,7 +35,7 @@ u32 ivpu_hw_btrs_dpu_max_freq_get(struct ivpu_device *vdev); + bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); + bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); + int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent); ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); + u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); +-- +2.51.0 + diff --git a/queue-6.12/accel-ivpu-prevent-runtime-suspend-during-context-ab.patch b/queue-6.12/accel-ivpu-prevent-runtime-suspend-during-context-ab.patch new file mode 100644 index 0000000000..51ab2834ed --- /dev/null +++ b/queue-6.12/accel-ivpu-prevent-runtime-suspend-during-context-ab.patch @@ -0,0 +1,66 @@ +From bf738beb8b61dda33c95d38081f11e6e26f2ad14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Feb 2025 09:46:18 +0100 +Subject: accel/ivpu: Prevent runtime suspend during context abort work + +From: Andrzej Kacprowski + +[ Upstream commit 7806bad76ac397a767f0c369534133c71c73b157 ] + +Increment the runtime PM counter when entering +ivpu_context_abort_work_fn() to prevent the device +from suspending while the function is executing. + +Reviewed-by: Jacek Lawrynowicz +Signed-off-by: Andrzej Kacprowski +Signed-off-by: Jacek Lawrynowicz +Link: https://patchwork.freedesktop.org/patch/msgid/20250204084622.2422544-3-jacek.lawrynowicz@linux.intel.com +Stable-dep-of: 9f6c63285737 ("accel/ivpu: Ensure rpm_runtime_put in case of engine reset/resume fail") +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_job.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index e631098718b15..a0dca1c253b74 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -8,6 +8,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -848,6 +849,9 @@ void ivpu_context_abort_thread_handler(struct work_struct *work) + struct ivpu_job *job; + unsigned long id; + ++ if (drm_WARN_ON(&vdev->drm, pm_runtime_get_if_active(vdev->drm.dev) <= 0)) ++ return; ++ + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (ivpu_jsm_reset_engine(vdev, 0)) + return; +@@ -864,7 +868,7 @@ void ivpu_context_abort_thread_handler(struct work_struct *work) + mutex_unlock(&vdev->context_list_lock); + + if (vdev->fw->sched_mode != VPU_SCHEDULING_MODE_HW) +- return; ++ goto runtime_put; + + if (ivpu_jsm_hws_resume_engine(vdev, 0)) + return; +@@ -878,4 +882,8 @@ void ivpu_context_abort_thread_handler(struct work_struct *work) + if (job->file_priv->aborted) + ivpu_job_signal_and_destroy(vdev, job->job_id, DRM_IVPU_JOB_STATUS_ABORTED); + mutex_unlock(&vdev->submitted_jobs_lock); ++ ++runtime_put: ++ pm_runtime_mark_last_busy(vdev->drm.dev); ++ pm_runtime_put_autosuspend(vdev->drm.dev); + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-6.12/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..074def8979 --- /dev/null +++ b/queue-6.12/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 78ae8d94af2f821e1e93e41a2beaad5940ca971e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 9b6b71a2ffb54..a4498357bd165 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-6.12/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-6.12/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..5f0dbb2d36 --- /dev/null +++ b/queue-6.12/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 61722e5c9baf713c1361e3c0f687f756589adca7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index b51b947b0ca5b..b7ee463e757d2 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1693,6 +1693,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch b/queue-6.12/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch new file mode 100644 index 0000000000..d7049d4abe --- /dev/null +++ b/queue-6.12/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch @@ -0,0 +1,41 @@ +From 9355f0c5e74d39246a2c9b5a646d48055c6d5c6a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:38:51 +0200 +Subject: ARM: dts: am335x-netcom-plus-2xx: add missing GPIO labels + +From: Yegor Yefremov + +[ Upstream commit d0c4b1723c419a18cb434903c7754954ecb51d35 ] + +Fixes: 8e9d75fd2ec2 ("ARM: dts: am335x-netcom: add GPIO names for NetCom Plus 2-port devices") + +Signed-off-by: Yegor Yefremov +Link: https://lore.kernel.org/r/20251007103851.3765678-1-yegorslists@googlemail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +index f66d57bb685ee..f0519ab301416 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +@@ -222,10 +222,10 @@ &gpio3 { + "ModeA1", + "ModeA2", + "ModeA3", +- "NC", +- "NC", +- "NC", +- "NC", ++ "ModeB0", ++ "ModeB1", ++ "ModeB2", ++ "ModeB3", + "NC", + "NC", + "NC", +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch b/queue-6.12/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch new file mode 100644 index 0000000000..fcd3fa803f --- /dev/null +++ b/queue-6.12/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch @@ -0,0 +1,43 @@ +From 142db10f76ecdb0f8a9d5067b73849adc363a824 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:15 +0200 +Subject: ARM: dts: omap3: beagle-xm: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit f7f3bc18300a230e0f1bfb17fc8889435c1e47f5 ] + +The "ti,twl4030-power-beagleboard-xm" compatible string is obsolete and +is not supported by any in-kernel driver. Currently, the kernel falls +back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a +driver to this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: 9188883fd66e9 ("ARM: dts: Enable twl4030 off-idle configuration for selected omaps") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-3-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +index 08ee0f8ea68fd..71b39a923d37c 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +@@ -291,7 +291,7 @@ codec { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch b/queue-6.12/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch new file mode 100644 index 0000000000..7cba152a9c --- /dev/null +++ b/queue-6.12/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch @@ -0,0 +1,43 @@ +From 2dc0a379dd38f57c95c0e33f821f11fa577464fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:16 +0200 +Subject: ARM: dts: omap3: n900: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit 3862123e9b56663c7a3e4a308e6e65bffe44f646 ] + +The "ti,twl4030-power-n900" compatible string is obsolete and is not +supported by any in-kernel driver. Currently, the kernel falls back to +the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to +this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: daebabd578647 ("mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-4-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-n900.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +index 4bde3342bb959..598a4885094d3 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +@@ -508,7 +508,7 @@ twl_audio: audio { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-renesas-gose-remove-superfluous-port-propert.patch b/queue-6.12/arm-dts-renesas-gose-remove-superfluous-port-propert.patch new file mode 100644 index 0000000000..6c6391e32a --- /dev/null +++ b/queue-6.12/arm-dts-renesas-gose-remove-superfluous-port-propert.patch @@ -0,0 +1,39 @@ +From 5cb6285b14e9361dc5278798000dfe91d2d3fabc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 11:36:02 +0200 +Subject: ARM: dts: renesas: gose: Remove superfluous port property + +From: Wolfram Sang + +[ Upstream commit 00df14f34615630f92f97c9d6790bd9d25c4242d ] + +'bus-width' is defined for the corresponding vin input port already. +No need to declare it in the output port again. Fixes: + + arch/arm/boot/dts/renesas/r8a7793-gose.dtb: composite-in@20 (adi,adv7180cp): ports:port@3:endpoint: Unevaluated properties are not allowed ('bus-width' was unexpected) + from schema $id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml# + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250929093616.17679-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r8a7793-gose.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +index 1ea6c757893bc..1a4e44c3c5af6 100644 +--- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts ++++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +@@ -373,7 +373,6 @@ adv7180_in: endpoint { + port@3 { + reg = <3>; + adv7180_out: endpoint { +- bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch b/queue-6.12/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch new file mode 100644 index 0000000000..210ba3680a --- /dev/null +++ b/queue-6.12/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch @@ -0,0 +1,41 @@ +From 5edebb39c3f432074c9f0d7f4b5e0961770e11bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:46:25 +0200 +Subject: ARM: dts: renesas: r9a06g032-rzn1d400-db: Drop invalid #cells + properties + +From: Wolfram Sang + +[ Upstream commit ca7fffb6e92a7c93604ea2bae0e1c89b20750937 ] + +The 'ethernet-ports' node in the SoC DTSI handles them already. Fixes: + + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dtb: switch@44050000 (renesas,r9a06g032-a5psw): Unevaluated properties are not allowed ('#address-cells', '#size-cells' were unexpected) + from schema $id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# + +Fixes: 5b6d7c3c5861ad4a ("ARM: dts: r9a06g032-rzn1d400-db: Add switch description") +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251007104624.19786-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +index 31cdca3e623cd..5fa7acce47149 100644 +--- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts ++++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +@@ -126,8 +126,6 @@ &rtc0 { + + &switch { + status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch b/queue-6.12/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..1346833148 --- /dev/null +++ b/queue-6.12/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 6c04c2abba7bd3bce01394f724885977e04887be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:16 +0100 +Subject: ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-3-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +index 0d8495792a702..0394b948443b3 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +@@ -853,6 +853,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&vtf_reg>; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch b/queue-6.12/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..573f45dbf3 --- /dev/null +++ b/queue-6.12/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From c238f5913c6ab47057e5c525c7f45852af2a3122 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:17 +0100 +Subject: ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97cc9c346b2c9cde075b9420fc172137d2427711 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: a19f6efc01df ("ARM: dts: exynos: Enable WLAN support for the Trats board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-4-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +index 95e0e01b6ff6b..6bd902cb8f4ad 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +@@ -518,6 +518,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&tflash_reg>; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch b/queue-6.12/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..34a928210f --- /dev/null +++ b/queue-6.12/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From c1a84b950eb45f989cd700d14f3d6f58c42bf579 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:18 +0100 +Subject: ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f77cbb9a3e5d ("ARM: dts: exynos: Add bcm4334 device node to Trats2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-5-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +index 3d5aace668dc5..977ecc838b0cb 100644 +--- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +@@ -1440,6 +1440,7 @@ &sdhci_3 { + #address-cells = <1>; + #size-cells = <0>; + non-removable; ++ cap-power-off-card; + bus-width = <4>; + + mmc-pwrseq = <&wlan_pwrseq>; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch b/queue-6.12/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch new file mode 100644 index 0000000000..3af30d0f66 --- /dev/null +++ b/queue-6.12/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch @@ -0,0 +1,43 @@ +From dd10f0bd52d1feae01f627dfef8ac28b23faeb8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:15 +0100 +Subject: ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97aee67e2406ea381408915e606c5f86448f3949 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f1b0ffaa686f ("ARM: dts: exynos: Enable WLAN support for the UniversalC210 board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-2-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +index bdc30f8cf748f..91490693432b6 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +@@ -610,6 +610,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&ldo5_reg>; +-- +2.51.0 + diff --git a/queue-6.12/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch b/queue-6.12/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch new file mode 100644 index 0000000000..48d94dce34 --- /dev/null +++ b/queue-6.12/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch @@ -0,0 +1,50 @@ +From bc316de3a0b10c18fb2dd99b75a2751edbe4f694 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 00:46:11 +0200 +Subject: ARM: dts: stm32: stm32mp157c-phycore: Fix STMPE811 touchscreen node + properties + +From: Jihed Chaibi + +[ Upstream commit e40b061cd379f4897e705d17cf1b4572ad0f3963 ] + +Move st,adc-freq, st,mod-12b, st,ref-sel, and st,sample-time properties +from the touchscreen subnode to the parent touch@44 node. These properties +are defined in the st,stmpe.yaml schema for the parent node, not the +touchscreen subnode, resolving the validation error about unevaluated +properties. + +Fixes: 27538a18a4fcc ("ARM: dts: stm32: add STM32MP1-based Phytec SoM") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250915224611.169980-1-jihed.chaibi.dev@gmail.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + .../boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +index bf0c32027baf7..370b2afbf15bf 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +@@ -185,13 +185,13 @@ touch@44 { + interrupt-parent = <&gpioi>; + vio-supply = <&v3v3>; + vcc-supply = <&v3v3>; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <1>; + + touchscreen { + compatible = "st,stmpe-ts"; +- st,sample-time = <4>; +- st,mod-12b = <1>; +- st,ref-sel = <0>; +- st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch b/queue-6.12/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch new file mode 100644 index 0000000000..f2e83c13a5 --- /dev/null +++ b/queue-6.12/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch @@ -0,0 +1,45 @@ +From 8fcf006f8dc2ed4b4efc80a8440d50bfcf5599fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 21:51:34 +0100 +Subject: arm64: dts: exynos: gs101: fix sysreg_apm reg property +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Griffin + +[ Upstream commit 4348c22a4f15dbef1314f1a353d7f053b24e9ace ] + +Both the start address and size are incorrect for the apm_sysreg DT +node. Update to match the TRM (rather than how it was defined +downstream). + +Fixes: ea89fdf24fd9 ("arm64: dts: exynos: google: Add initial Google gs101 SoC support") +Signed-off-by: Peter Griffin +Reviewed-by: André Draszik +Link: https://patch.msgid.link/20251013-automatic-clocks-v1-5-72851ee00300@linaro.org +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/exynos/google/gs101.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +index a509a59def428..d03987cc4370c 100644 +--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi ++++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +@@ -1390,9 +1390,9 @@ cmu_apm: clock-controller@17400000 { + clock-names = "oscclk"; + }; + +- sysreg_apm: syscon@174204e0 { ++ sysreg_apm: syscon@17420000 { + compatible = "google,gs101-apm-sysreg", "syscon"; +- reg = <0x174204e0 0x1000>; ++ reg = <0x17420000 0x10000>; + }; + + pmu_system_controller: system-controller@17460000 { +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch b/queue-6.12/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch new file mode 100644 index 0000000000..5bd7ac577e --- /dev/null +++ b/queue-6.12/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch @@ -0,0 +1,38 @@ +From 70081a6cda6f9cc1ce41c7409687200796f58f21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:45 -0700 +Subject: arm64: dts: freescale: imx8mp-venice-gw7905-2x: remove duplicate + usdhc1 props + +From: Tim Harvey + +[ Upstream commit 8b7e58ab4a02601a0e86e9f9701d4612038d8b29 ] + +Remove the un-intended duplicate properties from usdhc1. + +Fixes: 0d5b288c2110e ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 6c75a5ecf56bb..45c7082c9df71 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -421,9 +421,6 @@ &usdhc1 { + bus-width = <4>; + non-removable; + status = "okay"; +- bus-width = <4>; +- non-removable; +- status = "okay"; + }; + + /* eMMC */ +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-6.12/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..92e6eb3c8d --- /dev/null +++ b/queue-6.12/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From 1408267a352a5c6b84f8fada5d1ef4650e34c072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 752caa38eb03b..266038fbbef97 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -351,17 +351,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch b/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch new file mode 100644 index 0000000000..358bc5ed33 --- /dev/null +++ b/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch @@ -0,0 +1,87 @@ +From a2c9fdc98b2bb88c4871549f9faaa96adfd302cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:51 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board sdhc1 + +From: Tim Harvey + +[ Upstream commit 9db04b310ef99b546e4240c55842e81b06b78579 ] + +SDHC1 on the GW702x SOM routes to a connector for use on a baseboard +and as such are defined in the baseboard device-trees. + +Remove it from the gw702x SOM device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 20 ------------------- + .../dts/freescale/imx8mp-venice-gw72xx.dtsi | 11 ---------- + 2 files changed, 31 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index e8688695df780..4e89aa9ce9ad2 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -400,15 +400,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board */ +-&usdhc1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_usdhc1>; +- bus-width = <4>; +- non-removable; +- status = "okay"; +-}; +- + /* eMMC */ + &usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; +@@ -509,17 +500,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +index cf747ec6fa16e..76020ef89bf3e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +@@ -365,17 +365,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch b/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch new file mode 100644 index 0000000000..b0e25cb2a6 --- /dev/null +++ b/queue-6.12/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch @@ -0,0 +1,85 @@ +From 779b4e22562c9a03eb2bd26a2c09fe567278e534 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:50 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board uart + +From: Tim Harvey + +[ Upstream commit effe98060f70eb96e142f656e750d6af275ceac3 ] + +UART1 and UART3 go to a connector for use on a baseboard and as such are +defined in the baseboard device-trees. Remove them from the gw702x SOM +device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 28 ------------------- + 1 file changed, 28 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 45c7082c9df71..e8688695df780 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -393,13 +393,6 @@ &i2c3 { + status = "okay"; + }; + +-/* off-board header */ +-&uart1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart1>; +- status = "okay"; +-}; +- + /* console */ + &uart2 { + pinctrl-names = "default"; +@@ -407,13 +400,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board header */ +-&uart3 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart3>; +- status = "okay"; +-}; +- + /* off-board */ + &usdhc1 { + pinctrl-names = "default"; +@@ -516,13 +502,6 @@ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2 + >; + }; + +- pinctrl_uart1: uart1grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 +- MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 +- >; +- }; +- + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 +@@ -530,13 +509,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_uart3: uart3grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 +- MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 +- >; +- }; +- + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch b/queue-6.12/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch new file mode 100644 index 0000000000..b2c337b805 --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch @@ -0,0 +1,40 @@ +From e0c29d07fe5bdb66dfc222ccbd5daae64853c40b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:01 +0300 +Subject: arm64: dts: qcom: msm8996: add interconnect paths to USB2 controller + +From: Dmitry Baryshkov + +[ Upstream commit 242f7558e7bf54cb63c06506f7b0630dd67d45a4 ] + +Add the missing interconnects to the USB2 host. The Fixes tag points to +the commit which broke probing of the USB host on that platform. + +Fixes: 130733a10079 ("interconnect: qcom: msm8996: Promote to core_initcall") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Acked-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-2-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 0a8884145865d..932994f65b250 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3449,6 +3449,9 @@ usb2: usb@76f8800 { + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + ++ interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, ++ <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; ++ interconnect-names = "usb-ddr", "apps-usb"; + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch b/queue-6.12/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch new file mode 100644 index 0000000000..16fea4c490 --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch @@ -0,0 +1,43 @@ +From d83e2bcfcdfb15c1a525b1819e98254b7a8c5736 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 11:06:33 +0200 +Subject: arm64: dts: qcom: qcm6490-shift-otter: Add missing reserved-memory + +From: Alexander Martinz + +[ Upstream commit f404fdcb50021fdad6bc734d69468cc777901a80 ] + +It seems we also need to reserve a region of 81 MiB called "removed_mem" +otherwise we can easily hit memory errors with higher RAM usage. + +Fixes: 249666e34c24 ("arm64: dts: qcom: add QCM6490 SHIFTphone 8") +Signed-off-by: Alexander Martinz +Reviewed-by: Konrad Dybcio +Signed-off-by: Luca Weiss +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251009-otter-further-bringup-v2-3-5bb2f4a02cea@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +index 75930f9576966..ce5cd758e28b4 100644 +--- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts ++++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +@@ -118,6 +118,11 @@ cdsp_mem: cdsp@88f00000 { + no-map; + }; + ++ removed_mem: removed@c0000000 { ++ reg = <0x0 0xc0000000 0x0 0x5100000>; ++ no-map; ++ }; ++ + rmtfs_mem: rmtfs@f8500000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0xf8500000 0x0 0x600000>; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch b/queue-6.12/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch new file mode 100644 index 0000000000..4da0ff9900 --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch @@ -0,0 +1,41 @@ +From 15a331d1d810d022bea65fea2845f78cb4cf84f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Sep 2025 13:20:28 +0200 +Subject: arm64: dts: qcom: sdm845-oneplus: Correct gpio used for slider + +From: Gergo Koteles + +[ Upstream commit d7ec7d34237498fab7a6afed8da4b7139b0e387c ] + +The previous GPIO numbers were wrong. Update them to the correct +ones and fix the label. + +Fixes: 288ef8a42612 ("arm64: dts: sdm845: add oneplus6/6t devices") +Signed-off-by: Gergo Koteles +Signed-off-by: David Heidelberg +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250927-slider-correct-v1-1-fb8cc7fdcedf@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +index 46e25c53829ad..d0cbf9106a792 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +@@ -803,8 +803,8 @@ hall_sensor_default: hall-sensor-default-state { + bias-disable; + }; + +- tri_state_key_default: tri-state-key-default-state { +- pins = "gpio40", "gpio42", "gpio26"; ++ alert_slider_default: alert-slider-default-state { ++ pins = "gpio126", "gpio52", "gpio24"; + function = "gpio"; + drive-strength = <2>; + bias-disable; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch b/queue-6.12/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch new file mode 100644 index 0000000000..07eca033d0 --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch @@ -0,0 +1,47 @@ +From aae41f4b8b94595170e25fea8b463f5581d60bae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 20:53:44 +0200 +Subject: arm64: dts: qcom: sm8650: set ufs as dma coherent + +From: Neil Armstrong + +[ Upstream commit c2703c90161b45bca5b65f362adbae02ed71fcc1 ] + +The UFS device is ovbiously dma coherent like the other IOMMU devices +like usb, mmc, ... let's fix this by adding the flag. + +To be sure an extensive test has been performed to be sure it's +safe, as downstream uses this flag for UFS as well. + +As an experiment, I checked how the dma-coherent could impact +the UFS bandwidth, and it happens the max bandwidth on cached +write is slighly highter (up to 10%) while using less cpu time +since cache sync/flush is skipped. + +Fixes: 10e024671295 ("arm64: dts: qcom: sm8650: add interconnect dependent device nodes") +Signed-off-by: Neil Armstrong +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251007-topic-sm8650-upstream-ufs-dma-coherent-v1-1-f3cfeaee04ce@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi +index bd91624bd3bfc..6763c750f6801 100644 +--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi +@@ -2590,6 +2590,8 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + + iommus = <&apps_smmu 0x60 0>; + ++ dma-coherent; ++ + lanes-per-direction = <2>; + qcom,ice = <&ice>; + +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch b/queue-6.12/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch new file mode 100644 index 0000000000..60630b9986 --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch @@ -0,0 +1,39 @@ +From c06ecd370683879aeb8e6f8522280657d486e869 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 16:20:18 +0530 +Subject: arm64: dts: qcom: x1e80100: Add missing quirk for HS only USB + controller + +From: Krishna Kurapati + +[ Upstream commit 6b3e8a5d6c88609d9ce93789524f818cca0aa485 ] + +The PIPE clock is provided by the USB3 PHY, which is predictably not +connected to the HS-only controller. Add "qcom,select-utmi-as-pipe-clk" +quirk to HS only USB controller to disable pipe clock requirement. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20251024105019.2220832-2-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index b03f3ce250dbc..8536403e6ac99 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4272,6 +4272,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + interconnect-names = "usb-ddr", + "apps-usb"; + ++ qcom,select-utmi-as-pipe-clk; + wakeup-source; + + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch b/queue-6.12/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch new file mode 100644 index 0000000000..9fdb56f51c --- /dev/null +++ b/queue-6.12/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch @@ -0,0 +1,53 @@ +From 32caf0096ea9720214d4b56af79893b82eebbd51 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Oct 2025 17:26:30 +0530 +Subject: arm64: dts: qcom: x1e80100: Fix compile warnings for USB HS + controller + +From: Krishna Kurapati + +[ Upstream commit 0dab10c38282e6ef87ef88efb99d4106cce7ed33 ] + +With W=1, the following error comes up: + +Warning (graph_child_address): /soc@0/usb@a2f8800/usb@a200000/ports: graph node has single child node 'port@0', #address-cells/#size-cells are not necessary + +This could be since the controller is only HS capable and only one port +node is added. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251019115630.2222720-1-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index 5082ecb32089b..b03f3ce250dbc 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4287,15 +4287,8 @@ usb_2_dwc3: usb@a200000 { + + dma-coherent; + +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- +- usb_2_dwc3_hs: endpoint { +- }; ++ port { ++ usb_2_dwc3_hs: endpoint { + }; + }; + }; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch b/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch new file mode 100644 index 0000000000..b147936bbc --- /dev/null +++ b/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch @@ -0,0 +1,48 @@ +From af0b09c77d7f1497b503f7833e2b691359b8065e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:30 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 3069ff1930aa71e125874c780ffaa6caeda5800a ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is +vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1] +Describe this supply. + +[1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-3-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 7813984086b38..eeb3e84deec9f 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -209,6 +209,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcc_3v3_pmu>; + }; + }; + +@@ -543,7 +544,7 @@ regulator-state-mem { + }; + }; + +- vcc_3v3_s3: dcdc-reg8 { ++ vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-2219 b/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-2219 new file mode 100644 index 0000000000..f8a6264e06 --- /dev/null +++ b/queue-6.12/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-2219 @@ -0,0 +1,38 @@ +From 387399dc9f8a5625d55c42c6721e94a3ddf917b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:31 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C + +From: FUKAUMI Naoki + +[ Upstream commit 260316d35cf8f8606c5ed7a349cc92e1e71d8150 ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is +vcca1v8_pmu. [1] Describe this supply. + +[1] https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13 + +Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-4-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +index 887c9be1b4100..0649812765900 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +@@ -466,6 +466,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcca1v8_pmu>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch b/queue-6.12/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch new file mode 100644 index 0000000000..147facceca --- /dev/null +++ b/queue-6.12/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch @@ -0,0 +1,58 @@ +From 48171e9150734c52a5f35061a452cd2bbdcb77f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:29 +0000 +Subject: arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa + ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 92e6e0b0e595afdda6296c760551ad3ffe9d5231 ] + +The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the +i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0 +bus. + +[1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-2-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 294b99dd50da2..7813984086b38 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -204,6 +204,12 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; ++ ++ eeprom: eeprom@50 { ++ compatible = "belling,bl24c16a", "atmel,24c16"; ++ reg = <0x50>; ++ pagesize = <16>; ++ }; + }; + + &i2c2 { +@@ -225,12 +231,6 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; +- +- eeprom: eeprom@50 { +- compatible = "belling,bl24c16a", "atmel,24c16"; +- reg = <0x50>; +- pagesize = <16>; +- }; + }; + + &i2c3 { +-- +2.51.0 + diff --git a/queue-6.12/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch b/queue-6.12/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch new file mode 100644 index 0000000000..2652e29e21 --- /dev/null +++ b/queue-6.12/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch @@ -0,0 +1,40 @@ +From 4e0bf17f9f046ee695260737805bc22549ea1358 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 14:33:42 -0500 +Subject: arm64: dts: ti: k3-am62p: Fix memory ranges for GPU + +From: Randolph Sapp + +[ Upstream commit 76546090b1726118cd6fb3db7159fc2a3fdda8a0 ] + +Update the memory region listed in the k3-am62p.dtsi for the BXS-4-64 +GPU to match the Main Memory Map described in the TRM [1]. + +[1] https://www.ti.com/lit/ug/spruj83b/spruj83b.pdf + +Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs") +Signed-off-by: Randolph Sapp +Reviewed-by: Michael Walle +Link: https://patch.msgid.link/20250919193341.707660-2-rs@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +index 75a15c368c11b..dd24c40c7965d 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +@@ -59,7 +59,7 @@ cbass_main: bus@f0000 { + <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ + <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ +- <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ ++ <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ + <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ + <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ + <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ +-- +2.51.0 + diff --git a/queue-6.12/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-6.12/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..ffec744f51 --- /dev/null +++ b/queue-6.12/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From 0cfce396eaf0378c168d9a5d33adc79a108c64a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 0a67987c316e8..656a4d619cdf1 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1237,7 +1237,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, +-- +2.51.0 + diff --git a/queue-6.12/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-6.12/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..44081d4862 --- /dev/null +++ b/queue-6.12/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From e83d0c46aab346e9c1169d3ca4bf1bf192cf6027 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index ff1fa01acb85b..bc49843065c5c 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-6.12/asoc-nau8325-add-missing-build-config.patch b/queue-6.12/asoc-nau8325-add-missing-build-config.patch new file mode 100644 index 0000000000..9926a4b226 --- /dev/null +++ b/queue-6.12/asoc-nau8325-add-missing-build-config.patch @@ -0,0 +1,70 @@ +From b226c6a72478370987d82dfb3905f628c3e378b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:35 +0100 +Subject: ASoC: nau8325: add missing build config + +From: Jaroslav Kysela + +[ Upstream commit cd41d3420ef658b2ca902d7677536ec8e25b610a ] + +This configuration was missing from the initial commit. + +Found by Jiri Benc + +Fixes: c0a3873b9938 ("ASoC: nau8325: new driver") +Cc: Seven Lee +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-3-perex@perex.cz +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/Kconfig | 5 +++++ + sound/soc/codecs/Makefile | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 6a72561c4189b..399dcf3d1c64b 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -162,6 +162,7 @@ config SND_SOC_ALL_CODECS + imply SND_SOC_MT6359 + imply SND_SOC_MT6660 + imply SND_SOC_NAU8315 ++ imply SND_SOC_NAU8325 + imply SND_SOC_NAU8540 + imply SND_SOC_NAU8810 + imply SND_SOC_NAU8821 +@@ -2541,6 +2542,10 @@ config SND_SOC_MT6660 + config SND_SOC_NAU8315 + tristate "Nuvoton Technology Corporation NAU8315 CODEC" + ++config SND_SOC_NAU8325 ++ tristate "Nuvoton Technology Corporation NAU8325 CODEC" ++ depends on I2C ++ + config SND_SOC_NAU8540 + tristate "Nuvoton Technology Corporation NAU85L40 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index 69cb0b39f2200..47c621b3a0378 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -183,6 +183,7 @@ snd-soc-mt6359-y := mt6359.o + snd-soc-mt6359-accdet-y := mt6359-accdet.o + snd-soc-mt6660-y := mt6660.o + snd-soc-nau8315-y := nau8315.o ++snd-soc-nau8325-y := nau8325.o + snd-soc-nau8540-y := nau8540.o + snd-soc-nau8810-y := nau8810.o + snd-soc-nau8821-y := nau8821.o +@@ -585,6 +586,7 @@ obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o + obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o + obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o + obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o ++obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o + obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o + obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o + obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o +-- +2.51.0 + diff --git a/queue-6.12/asoc-nau8325-use-simple-i2c-probe-function.patch b/queue-6.12/asoc-nau8325-use-simple-i2c-probe-function.patch new file mode 100644 index 0000000000..32d904a707 --- /dev/null +++ b/queue-6.12/asoc-nau8325-use-simple-i2c-probe-function.patch @@ -0,0 +1,41 @@ +From c79a1f39308837cd627d74fe28c7d362c0361a96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:34 +0100 +Subject: ASoC: nau8325: use simple i2c probe function + +From: Jaroslav Kysela + +[ Upstream commit b4d072c98e47c562834f2a050ca98a1c709ef4f9 ] + +The i2c probe functions here don't use the id information provided in +their second argument, so the single-parameter i2c probe function +("probe_new") can be used instead. + +This avoids scanning the identifier tables during probes. + +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-2-perex@perex.cz +Signed-off-by: Mark Brown +Stable-dep-of: cd41d3420ef6 ("ASoC: nau8325: add missing build config") +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/nau8325.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/nau8325.c b/sound/soc/codecs/nau8325.c +index 2266f320a8f22..5b3115b0a7e58 100644 +--- a/sound/soc/codecs/nau8325.c ++++ b/sound/soc/codecs/nau8325.c +@@ -829,8 +829,7 @@ static int nau8325_read_device_properties(struct device *dev, + return 0; + } + +-static int nau8325_i2c_probe(struct i2c_client *i2c, +- const struct i2c_device_id *id) ++static int nau8325_i2c_probe(struct i2c_client *i2c) + { + struct device *dev = &i2c->dev; + struct nau8325 *nau8325 = dev_get_platdata(dev); +-- +2.51.0 + diff --git a/queue-6.12/asoc-tas2781-correct-the-wrong-period.patch b/queue-6.12/asoc-tas2781-correct-the-wrong-period.patch new file mode 100644 index 0000000000..64a911fb33 --- /dev/null +++ b/queue-6.12/asoc-tas2781-correct-the-wrong-period.patch @@ -0,0 +1,37 @@ +From 5225834fe38208f67cf1c1278eca0fae38ff4fe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 07:44:27 +0800 +Subject: ASoC: tas2781: correct the wrong period + +From: Shenghao Ding + +[ Upstream commit 950167a99dfd27eeaf177092908c598a31c79a7e ] + +A wrong preiod at the end of the sentence was reported by one of my +customers. Their thorough code review is greatly appreciated. + +Fixes: 49e2e353fb0d ("ASoC: tas2781: Add Calibration Kcontrols for Chromebook") +Signed-off-by: Shenghao Ding +Link: https://patch.msgid.link/20251121234427.402-1-shenghao-ding@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2781-i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c +index 2f100cbfdc41f..282907b035064 100644 +--- a/sound/soc/codecs/tas2781-i2c.c ++++ b/sound/soc/codecs/tas2781-i2c.c +@@ -1258,7 +1258,7 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) + + /* + * Alloc kcontrol via devm_kzalloc(), which don't manually +- * free the kcontrol。 ++ * free the kcontrol. + */ + cali_ctrls = devm_kcalloc(priv->dev, nctrls, + sizeof(cali_ctrls[0]), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.12/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-6.12/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..23f382876a --- /dev/null +++ b/queue-6.12/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 16a04a2e04be989780284b891ac506c781d24a88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 7826006018457..f0c7e25537d1f 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-6.12/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-6.12/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..9267f3bea0 --- /dev/null +++ b/queue-6.12/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From 166d1c0953d594762b32fc14f097f6972f22eb45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-6.12/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch b/queue-6.12/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch new file mode 100644 index 0000000000..af23026eda --- /dev/null +++ b/queue-6.12/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch @@ -0,0 +1,73 @@ +From 7872de6bfb87fe1257fabd5527034ed8ba3fa8c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:54:32 -0800 +Subject: block/blk-throttle: Fix throttle slice time for SSDs + +From: Guenter Roeck + +[ Upstream commit f76581f9f1d29e32e120b0242974ba266e79de58 ] + +Commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD") +introduced device type specific throttle slices if BLK_DEV_THROTTLING_LOW +was enabled. Commit bf20ab538c81 ("blk-throttle: remove +CONFIG_BLK_DEV_THROTTLING_LOW") removed support for BLK_DEV_THROTTLING_LOW, +but left the device type specific throttle slices in place. This +effectively changed throttling behavior on systems with SSD which now use +a different and non-configurable slice time compared to non-SSD devices. +Practical impact is that throughput tests with low configured throttle +values (65536 bps) experience less than expected throughput on SSDs, +presumably due to rounding errors associated with the small throttle slice +time used for those devices. The same tests pass when setting the throttle +values to 65536 * 4 = 262144 bps. + +The original code sets the throttle slice time to DFL_THROTL_SLICE_HD if +CONFIG_BLK_DEV_THROTTLING_LOW is disabled. Restore that code to fix the +problem. With that, DFL_THROTL_SLICE_SSD is no longer necessary. Revert to +the original code and re-introduce DFL_THROTL_SLICE to replace both +DFL_THROTL_SLICE_HD and DFL_THROTL_SLICE_SSD. This effectively reverts +commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD"). + +While at it, also remove MAX_THROTL_SLICE since it is not used anymore. + +Fixes: bf20ab538c81 ("blk-throttle: remove CONFIG_BLK_DEV_THROTTLING_LOW") +Cc: Yu Kuai +Cc: Tejun Heo +Signed-off-by: Guenter Roeck +Signed-off-by: Khazhismel Kumykov +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-throttle.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/block/blk-throttle.c b/block/blk-throttle.c +index 6b82fcbd7e774..4aa66c07d2e83 100644 +--- a/block/blk-throttle.c ++++ b/block/blk-throttle.c +@@ -22,9 +22,7 @@ + #define THROTL_QUANTUM 32 + + /* Throttling is performed over a slice and after that slice is renewed */ +-#define DFL_THROTL_SLICE_HD (HZ / 10) +-#define DFL_THROTL_SLICE_SSD (HZ / 50) +-#define MAX_THROTL_SLICE (HZ) ++#define DFL_THROTL_SLICE (HZ / 10) + + /* A workqueue to queue throttle related work */ + static struct workqueue_struct *kthrotld_workqueue; +@@ -1229,10 +1227,7 @@ static int blk_throtl_init(struct gendisk *disk) + goto out; + } + +- if (blk_queue_nonrot(q)) +- td->throtl_slice = DFL_THROTL_SLICE_SSD; +- else +- td->throtl_slice = DFL_THROTL_SLICE_HD; ++ td->throtl_slice = DFL_THROTL_SLICE; + td->track_bio_latency = !queue_is_mq(q); + if (!td->track_bio_latency) + blk_stat_enable_accounting(q); +-- +2.51.0 + diff --git a/queue-6.12/block-mq-deadline-introduce-dd_start_request.patch b/queue-6.12/block-mq-deadline-introduce-dd_start_request.patch new file mode 100644 index 0000000000..6ea3d63823 --- /dev/null +++ b/queue-6.12/block-mq-deadline-introduce-dd_start_request.patch @@ -0,0 +1,74 @@ +From 4549edc15948d65f9fe356e1350827500c562281 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:02 -0700 +Subject: block/mq-deadline: Introduce dd_start_request() + +From: Bart Van Assche + +[ Upstream commit 93a358af59c6e8ab00b57cfdb1c437516a4948ca ] + +Prepare for adding a second caller of this function. No functionality +has been changed. + +Cc: Damien Le Moal +Cc: Yu Kuai +Cc: chengkaitao +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moal +Signed-off-by: Jens Axboe +Stable-dep-of: d60055cf5270 ("block/mq-deadline: Switch back to a single dispatch list") +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 19473a9b50440..690b51587301d 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -310,6 +310,19 @@ static bool started_after(struct deadline_data *dd, struct request *rq, + return time_after(start_time, latest_start); + } + ++static struct request *dd_start_request(struct deadline_data *dd, ++ enum dd_data_dir data_dir, ++ struct request *rq) ++{ ++ u8 ioprio_class = dd_rq_ioclass(rq); ++ enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; ++ ++ dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); ++ dd->per_prio[prio].stats.dispatched++; ++ rq->rq_flags |= RQF_STARTED; ++ return rq; ++} ++ + /* + * deadline_dispatch_requests selects the best request according to + * read/write expire, fifo_batch, etc and with a start time <= @latest_start. +@@ -320,8 +333,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + { + struct request *rq, *next_rq; + enum dd_data_dir data_dir; +- enum dd_prio prio; +- u8 ioprio_class; + + lockdep_assert_held(&dd->lock); + +@@ -415,12 +426,7 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + dd->batching++; + deadline_move_request(dd, per_prio, rq); + done: +- ioprio_class = dd_rq_ioclass(rq); +- prio = ioprio_class_to_prio[ioprio_class]; +- dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); +- dd->per_prio[prio].stats.dispatched++; +- rq->rq_flags |= RQF_STARTED; +- return rq; ++ return dd_start_request(dd, data_dir, rq); + } + + /* +-- +2.51.0 + diff --git a/queue-6.12/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch b/queue-6.12/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch new file mode 100644 index 0000000000..31693fd0ef --- /dev/null +++ b/queue-6.12/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch @@ -0,0 +1,227 @@ +From 31794223cb5f5de7f79f5f28100671ab0c7dbd7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:03 -0700 +Subject: block/mq-deadline: Switch back to a single dispatch list + +From: Bart Van Assche + +[ Upstream commit d60055cf52703a705b86fb25b9b7931ec7ee399c ] + +Commit c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +modified the behavior of request flag BLK_MQ_INSERT_AT_HEAD from +dispatching a request before other requests into dispatching a request +before other requests with the same I/O priority. This is not correct since +BLK_MQ_INSERT_AT_HEAD is used when requeuing requests and also when a flush +request is inserted. Both types of requests should be dispatched as soon +as possible. Hence, make the mq-deadline I/O scheduler again ignore the I/O +priority for BLK_MQ_INSERT_AT_HEAD requests. + +Cc: Damien Le Moal +Cc: Yu Kuai +Reported-by: chengkaitao +Closes: https://lore.kernel.org/linux-block/20251009155253.14611-1-pilgrimtao@gmail.com/ +Fixes: c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moalv +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 107 +++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 60 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 690b51587301d..74fdc795526ef 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -71,7 +71,6 @@ struct io_stats_per_prio { + * present on both sort_list[] and fifo_list[]. + */ + struct dd_per_prio { +- struct list_head dispatch; + struct rb_root sort_list[DD_DIR_COUNT]; + struct list_head fifo_list[DD_DIR_COUNT]; + /* Position of the most recently dispatched request. */ +@@ -84,6 +83,7 @@ struct deadline_data { + * run time data + */ + ++ struct list_head dispatch; + struct dd_per_prio per_prio[DD_PRIO_COUNT]; + + /* Data direction of latest dispatched request. */ +@@ -336,16 +336,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + + lockdep_assert_held(&dd->lock); + +- if (!list_empty(&per_prio->dispatch)) { +- rq = list_first_entry(&per_prio->dispatch, struct request, +- queuelist); +- if (started_after(dd, rq, latest_start)) +- return NULL; +- list_del_init(&rq->queuelist); +- data_dir = rq_data_dir(rq); +- goto done; +- } +- + /* + * batches are currently reads XOR writes + */ +@@ -425,7 +415,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + */ + dd->batching++; + deadline_move_request(dd, per_prio, rq); +-done: + return dd_start_request(dd, data_dir, rq); + } + +@@ -473,6 +462,14 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) + enum dd_prio prio; + + spin_lock(&dd->lock); ++ ++ if (!list_empty(&dd->dispatch)) { ++ rq = list_first_entry(&dd->dispatch, struct request, queuelist); ++ list_del_init(&rq->queuelist); ++ dd_start_request(dd, rq_data_dir(rq), rq); ++ goto unlock; ++ } ++ + rq = dd_dispatch_prio_aged_requests(dd, now); + if (rq) + goto unlock; +@@ -577,10 +574,10 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) + + eq->elevator_data = dd; + ++ INIT_LIST_HEAD(&dd->dispatch); + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + +- INIT_LIST_HEAD(&per_prio->dispatch); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_READ]); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_WRITE]); + per_prio->sort_list[DD_READ] = RB_ROOT; +@@ -687,7 +684,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + trace_block_rq_insert(rq); + + if (flags & BLK_MQ_INSERT_AT_HEAD) { +- list_add(&rq->queuelist, &per_prio->dispatch); ++ list_add(&rq->queuelist, &dd->dispatch); + rq->fifo_time = jiffies; + } else { + struct list_head *insert_before; +@@ -757,8 +754,7 @@ static void dd_finish_request(struct request *rq) + + static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) + { +- return !list_empty_careful(&per_prio->dispatch) || +- !list_empty_careful(&per_prio->fifo_list[DD_READ]) || ++ return !list_empty_careful(&per_prio->fifo_list[DD_READ]) || + !list_empty_careful(&per_prio->fifo_list[DD_WRITE]); + } + +@@ -767,6 +763,9 @@ static bool dd_has_work(struct blk_mq_hw_ctx *hctx) + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + enum dd_prio prio; + ++ if (!list_empty_careful(&dd->dispatch)) ++ return true; ++ + for (prio = 0; prio <= DD_PRIO_MAX; prio++) + if (dd_has_work_for_prio(&dd->per_prio[prio])) + return true; +@@ -975,49 +974,39 @@ static int dd_owned_by_driver_show(void *data, struct seq_file *m) + return 0; + } + +-#define DEADLINE_DISPATCH_ATTR(prio) \ +-static void *deadline_dispatch##prio##_start(struct seq_file *m, \ +- loff_t *pos) \ +- __acquires(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- spin_lock(&dd->lock); \ +- return seq_list_start(&per_prio->dispatch, *pos); \ +-} \ +- \ +-static void *deadline_dispatch##prio##_next(struct seq_file *m, \ +- void *v, loff_t *pos) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- return seq_list_next(v, &per_prio->dispatch, pos); \ +-} \ +- \ +-static void deadline_dispatch##prio##_stop(struct seq_file *m, void *v) \ +- __releases(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- \ +- spin_unlock(&dd->lock); \ +-} \ +- \ +-static const struct seq_operations deadline_dispatch##prio##_seq_ops = { \ +- .start = deadline_dispatch##prio##_start, \ +- .next = deadline_dispatch##prio##_next, \ +- .stop = deadline_dispatch##prio##_stop, \ +- .show = blk_mq_debugfs_rq_show, \ ++static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) ++ __acquires(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_lock(&dd->lock); ++ return seq_list_start(&dd->dispatch, *pos); + } + +-DEADLINE_DISPATCH_ATTR(0); +-DEADLINE_DISPATCH_ATTR(1); +-DEADLINE_DISPATCH_ATTR(2); +-#undef DEADLINE_DISPATCH_ATTR ++static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ return seq_list_next(v, &dd->dispatch, pos); ++} ++ ++static void deadline_dispatch_stop(struct seq_file *m, void *v) ++ __releases(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_unlock(&dd->lock); ++} ++ ++static const struct seq_operations deadline_dispatch_seq_ops = { ++ .start = deadline_dispatch_start, ++ .next = deadline_dispatch_next, ++ .stop = deadline_dispatch_stop, ++ .show = blk_mq_debugfs_rq_show, ++}; + + #define DEADLINE_QUEUE_DDIR_ATTRS(name) \ + {#name "_fifo_list", 0400, \ +@@ -1040,9 +1029,7 @@ static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { + {"batching", 0400, deadline_batching_show}, + {"starved", 0400, deadline_starved_show}, + {"async_depth", 0400, dd_async_depth_show}, +- {"dispatch0", 0400, .seq_ops = &deadline_dispatch0_seq_ops}, +- {"dispatch1", 0400, .seq_ops = &deadline_dispatch1_seq_ops}, +- {"dispatch2", 0400, .seq_ops = &deadline_dispatch2_seq_ops}, ++ {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, + {"owned_by_driver", 0400, dd_owned_by_driver_show}, + {"queued", 0400, dd_queued_show}, + {}, +-- +2.51.0 + diff --git a/queue-6.12/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch b/queue-6.12/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch new file mode 100644 index 0000000000..aa8c559159 --- /dev/null +++ b/queue-6.12/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch @@ -0,0 +1,69 @@ +From 00eee98c08a2c7c7cc2fc3af062cd8b985a8abcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:23:30 -0800 +Subject: bpf: Check skb->transport_header is set in bpf_skb_check_mtu + +From: Martin KaFai Lau + +[ Upstream commit d946f3c98328171fa50ddb908593cf833587f725 ] + +The bpf_skb_check_mtu helper needs to use skb->transport_header when +the BPF_MTU_CHK_SEGS flag is used: + + bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) + +The transport_header is not always set. There is a WARN_ON_ONCE +report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + +bpf_prog_test_run is used: + +WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 + skb_gso_validate_network_len + bpf_skb_check_mtu + bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch + bpf_test_run + bpf_prog_test_run_skb + +For a normal ingress skb (not test_run), skb_reset_transport_header +is performed but there is plan to avoid setting it as described in +commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). + +This patch fixes the bpf helper by checking +skb_transport_header_was_set(). The check is done just before +skb->transport_header is used, to avoid breaking the existing bpf prog. +The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. + +Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") +Cc: Jesper Dangaard Brouer +Reported-by: Kaiyan Mei +Reported-by: Yinhao Hu +Signed-off-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 89ed625e14744..0d1f93f944f24 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -6353,9 +6353,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, + */ + if (skb_is_gso(skb)) { + ret = BPF_MTU_CHK_RET_SUCCESS; +- if (flags & BPF_MTU_CHK_SEGS && +- !skb_gso_validate_network_len(skb, mtu)) +- ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ if (flags & BPF_MTU_CHK_SEGS) { ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ if (!skb_gso_validate_network_len(skb, mtu)) ++ ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ } + } + out: + *mtu_len = mtu; +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-invalid-prog-stats-access-when-update_effect.patch b/queue-6.12/bpf-fix-invalid-prog-stats-access-when-update_effect.patch new file mode 100644 index 0000000000..b5e37c6480 --- /dev/null +++ b/queue-6.12/bpf-fix-invalid-prog-stats-access-when-update_effect.patch @@ -0,0 +1,91 @@ +From 419ca6b5595257c7050f913fcb931bd93277dcdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:23:43 +0000 +Subject: bpf: Fix invalid prog->stats access when update_effective_progs fails + +From: Pu Lehui + +[ Upstream commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc ] + +Syzkaller triggers an invalid memory access issue following fault +injection in update_effective_progs. The issue can be described as +follows: + +__cgroup_bpf_detach + update_effective_progs + compute_effective_progs + bpf_prog_array_alloc <-- fault inject + purge_effective_progs + /* change to dummy_bpf_prog */ + array->items[index] = &dummy_bpf_prog.prog + +---softirq start--- +__do_softirq + ... + __cgroup_bpf_run_filter_skb + __bpf_prog_run_save_cb + bpf_prog_run + stats = this_cpu_ptr(prog->stats) + /* invalid memory access */ + flags = u64_stats_update_begin_irqsave(&stats->syncp) +---softirq end--- + + static_branch_dec(&cgroup_bpf_enabled_key[atype]) + +The reason is that fault injection caused update_effective_progs to fail +and then changed the original prog into dummy_bpf_prog.prog in +purge_effective_progs. Then a softirq came, and accessing the members of +dummy_bpf_prog.prog in the softirq triggers invalid mem access. + +To fix it, skip updating stats when stats is NULL. + +Fixes: 492ecee892c2 ("bpf: enable program stats") +Signed-off-by: Pu Lehui +Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 12 +++++++----- + kernel/bpf/syscall.c | 3 +++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index 9b6908291de7c..a91f2babf4253 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -692,11 +692,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; +- stats = this_cpu_ptr(prog->stats); +- flags = u64_stats_update_begin_irqsave(&stats->syncp); +- u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, duration); +- u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ if (likely(prog->stats)) { ++ stats = this_cpu_ptr(prog->stats); ++ flags = u64_stats_update_begin_irqsave(&stats->syncp); ++ u64_stats_inc(&stats->cnt); ++ u64_stats_add(&stats->nsecs, duration); ++ u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ } + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index ba4543e771a6e..04c8755c0b951 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2281,6 +2281,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) + struct bpf_prog_stats *stats; + unsigned int flags; + ++ if (unlikely(!prog->stats)) ++ return; ++ + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch b/queue-6.12/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch new file mode 100644 index 0000000000..5b1532a63e --- /dev/null +++ b/queue-6.12/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch @@ -0,0 +1,83 @@ +From 65423b81d948a9187114bc4fe8f9dfa5ab310511 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:29:41 +0000 +Subject: bpf: Fix stackmap overflow check in __bpf_get_stackid() + +From: Arnaud Lecomte + +[ Upstream commit 23f852daa4bab4d579110e034e4d513f7d490846 ] + +Syzkaller reported a KASAN slab-out-of-bounds write in __bpf_get_stackid() +when copying stack trace data. The issue occurs when the perf trace + contains more stack entries than the stack map bucket can hold, + leading to an out-of-bounds write in the bucket's data array. + +Fixes: ee2a098851bf ("bpf: Adjust BPF stack helper functions to accommodate skip > 0") +Reported-by: syzbot+c9b724fbb41cf2538b7b@syzkaller.appspotmail.com +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192941.1500-1-contact@arnaud-lcm.com + +Closes: https://syzkaller.appspot.com/bug?extid=c9b724fbb41cf2538b7b +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index d6027bac61c35..4abb01f281fe4 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -251,8 +251,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + { + struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map); + struct stack_map_bucket *bucket, *new_bucket, *old_bucket; ++ u32 hash, id, trace_nr, trace_len, i, max_depth; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +- u32 hash, id, trace_nr, trace_len, i; + bool user = flags & BPF_F_USER_STACK; + u64 *ips; + bool hash_matches; +@@ -261,7 +261,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + /* skipping more than usable stack trace */ + return -EFAULT; + +- trace_nr = trace->nr - skip; ++ max_depth = stack_map_calculate_max_depth(map->value_size, stack_map_data_size(map), flags); ++ trace_nr = min_t(u32, trace->nr - skip, max_depth - skip); + trace_len = trace_nr * sizeof(u64); + ips = trace->ip + skip; + hash = jhash2((u32 *)ips, trace_len / sizeof(u32), 0); +@@ -390,15 +391,11 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + return -EFAULT; + + nr_kernel = count_kernel_ip(trace); ++ __u64 nr = trace->nr; /* save original */ + + if (kernel) { +- __u64 nr = trace->nr; +- + trace->nr = nr_kernel; + ret = __bpf_get_stackid(map, trace, flags); +- +- /* restore nr */ +- trace->nr = nr; + } else { /* user */ + u64 skip = flags & BPF_F_SKIP_FIELD_MASK; + +@@ -409,6 +406,10 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + flags = (flags & ~BPF_F_SKIP_FIELD_MASK) | skip; + ret = __bpf_get_stackid(map, trace, flags); + } ++ ++ /* restore nr */ ++ trace->nr = nr; ++ + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/bpf-free-special-fields-when-update-lru_-percpu_hash.patch b/queue-6.12/bpf-free-special-fields-when-update-lru_-percpu_hash.patch new file mode 100644 index 0000000000..696cdedbf8 --- /dev/null +++ b/queue-6.12/bpf-free-special-fields-when-update-lru_-percpu_hash.patch @@ -0,0 +1,58 @@ +From 5c9cfe57f9cb731a505b86c4ecb1418c88da5b8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 23:14:06 +0800 +Subject: bpf: Free special fields when update [lru_,]percpu_hash maps + +From: Leon Hwang + +[ Upstream commit 6af6e49a76c9af7d42eb923703e7648cb2bf401a ] + +As [lru_,]percpu_hash maps support BPF_KPTR_{REF,PERCPU}, missing +calls to 'bpf_obj_free_fields()' in 'pcpu_copy_value()' could cause the +memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the +map gets freed. + +Fix this by calling 'bpf_obj_free_fields()' after +'copy_map_value[,_long]()' in 'pcpu_copy_value()'. + +Fixes: 65334e64a493 ("bpf: Support kptrs in percpu hashmap and percpu LRU hashmap") +Signed-off-by: Leon Hwang +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20251105151407.12723-2-leon.hwang@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 570e2f7231443..26883a997e717 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -961,15 +961,21 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) + static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, + void *value, bool onallcpus) + { ++ void *ptr; ++ + if (!onallcpus) { + /* copy true value_size bytes */ +- copy_map_value(&htab->map, this_cpu_ptr(pptr), value); ++ ptr = this_cpu_ptr(pptr); ++ copy_map_value(&htab->map, ptr, value); ++ bpf_obj_free_fields(htab->map.record, ptr); + } else { + u32 size = round_up(htab->map.value_size, 8); + int off = 0, cpu; + + for_each_possible_cpu(cpu) { +- copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value + off); ++ ptr = per_cpu_ptr(pptr, cpu); ++ copy_map_value_long(&htab->map, ptr, value + off); ++ bpf_obj_free_fields(htab->map.record, ptr); + off += size; + } + } +-- +2.51.0 + diff --git a/queue-6.12/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch b/queue-6.12/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch new file mode 100644 index 0000000000..b10c4db81c --- /dev/null +++ b/queue-6.12/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch @@ -0,0 +1,40 @@ +From 2528d5e15635b34f4fa06fd38333b8b9b51a60b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:07:05 +0800 +Subject: bpf: Handle return value of ftrace_set_filter_ip in register_fentry + +From: Menglong Dong + +[ Upstream commit fea3f5e83c5cd80a76d97343023a2f2e6bd862bf ] + +The error that returned by ftrace_set_filter_ip() in register_fentry() is +not handled properly. Just fix it. + +Fixes: 00963a2e75a8 ("bpf: Support bpf_trampoline on functions with IPMODIFY (e.g. livepatch)") +Signed-off-by: Menglong Dong +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251110120705.1553694-1-dongml2@chinatelecom.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/trampoline.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index fabc8d2fc80e6..dbe7754b4f4e1 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -220,7 +220,9 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr) + } + + if (tr->func.ftrace_managed) { +- ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ if (ret) ++ return ret; + ret = register_ftrace_direct(tr->fops, (long)new_addr); + } else { + ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); +-- +2.51.0 + diff --git a/queue-6.12/bpf-refactor-stack-map-trace-depth-calculation-into-.patch b/queue-6.12/bpf-refactor-stack-map-trace-depth-calculation-into-.patch new file mode 100644 index 0000000000..419b43661d --- /dev/null +++ b/queue-6.12/bpf-refactor-stack-map-trace-depth-calculation-into-.patch @@ -0,0 +1,135 @@ +From c168989de953178a951b9da2dc439cb115982ea9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:28:58 +0000 +Subject: bpf: Refactor stack map trace depth calculation into helper function + +From: Arnaud Lecomte + +[ Upstream commit e17d62fedd10ae56e2426858bd0757da544dbc73 ] + +Extract the duplicated maximum allowed depth computation for stack +traces stored in BPF stacks from bpf_get_stackid() and __bpf_get_stack() +into a dedicated stack_map_calculate_max_depth() helper function. + +This unifies the logic for: +- The max depth computation +- Enforcing the sysctl_perf_event_max_stack limit + +No functional changes for existing code paths. + +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192858.31424-1-contact@arnaud-lcm.com +Stable-dep-of: 23f852daa4ba ("bpf: Fix stackmap overflow check in __bpf_get_stackid()") +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 47 +++++++++++++++++++++++++++++-------------- + 1 file changed, 32 insertions(+), 15 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index ec3a57a5fba1f..d6027bac61c35 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -42,6 +42,28 @@ static inline int stack_map_data_size(struct bpf_map *map) + sizeof(struct bpf_stack_build_id) : sizeof(u64); + } + ++/** ++ * stack_map_calculate_max_depth - Calculate maximum allowed stack trace depth ++ * @size: Size of the buffer/map value in bytes ++ * @elem_size: Size of each stack trace element ++ * @flags: BPF stack trace flags (BPF_F_USER_STACK, BPF_F_USER_BUILD_ID, ...) ++ * ++ * Return: Maximum number of stack trace entries that can be safely stored ++ */ ++static u32 stack_map_calculate_max_depth(u32 size, u32 elem_size, u64 flags) ++{ ++ u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 max_depth; ++ u32 curr_sysctl_max_stack = READ_ONCE(sysctl_perf_event_max_stack); ++ ++ max_depth = size / elem_size; ++ max_depth += skip; ++ if (max_depth > curr_sysctl_max_stack) ++ return curr_sysctl_max_stack; ++ ++ return max_depth; ++} ++ + static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) + { + u64 elem_size = sizeof(struct stack_map_bucket) + +@@ -300,20 +322,17 @@ static long __bpf_get_stackid(struct bpf_map *map, + BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, + u64, flags) + { +- u32 max_depth = map->value_size / stack_map_data_size(map); +- u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 elem_size = stack_map_data_size(map); + bool user = flags & BPF_F_USER_STACK; + struct perf_callchain_entry *trace; + bool kernel = !user; ++ u32 max_depth; + + if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK | + BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) + return -EINVAL; + +- max_depth += skip; +- if (max_depth > sysctl_perf_event_max_stack) +- max_depth = sysctl_perf_event_max_stack; +- ++ max_depth = stack_map_calculate_max_depth(map->value_size, elem_size, flags); + trace = get_perf_callchain(regs, kernel, user, max_depth, + false, false); + +@@ -406,7 +425,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + struct perf_callchain_entry *trace_in, + void *buf, u32 size, u64 flags, bool may_fault) + { +- u32 trace_nr, copy_len, elem_size, num_elem, max_depth; ++ u32 trace_nr, copy_len, elem_size, max_depth; + bool user_build_id = flags & BPF_F_USER_BUILD_ID; + bool crosstask = task && task != current; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +@@ -438,21 +457,20 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + goto clear; + } + +- num_elem = size / elem_size; +- max_depth = num_elem + skip; +- if (sysctl_perf_event_max_stack < max_depth) +- max_depth = sysctl_perf_event_max_stack; ++ max_depth = stack_map_calculate_max_depth(size, elem_size, flags); + + if (may_fault) + rcu_read_lock(); /* need RCU for perf's callchain below */ + +- if (trace_in) ++ if (trace_in) { + trace = trace_in; +- else if (kernel && task) ++ trace->nr = min_t(u32, trace->nr, max_depth); ++ } else if (kernel && task) { + trace = get_callchain_entry_for_task(task, max_depth); +- else ++ } else { + trace = get_perf_callchain(regs, kernel, user, max_depth, + crosstask, false); ++ } + + if (unlikely(!trace) || trace->nr < skip) { + if (may_fault) +@@ -461,7 +479,6 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + } + + trace_nr = trace->nr - skip; +- trace_nr = (trace_nr <= num_elem) ? trace_nr : num_elem; + copy_len = trace_nr * elem_size; + + ips = trace->ip + skip; +-- +2.51.0 + diff --git a/queue-6.12/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch b/queue-6.12/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch new file mode 100644 index 0000000000..d62a5feb73 --- /dev/null +++ b/queue-6.12/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch @@ -0,0 +1,41 @@ +From 67baf034540aed80d14b5861947d4742a5ab3d96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:45 +0000 +Subject: btrfs: fix leaf leak in an error path in btrfs_del_items() + +From: Filipe Manana + +[ Upstream commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 ] + +If the call to btrfs_del_leaf() fails we return without decrementing the +extra ref we took on the leaf, therefore leaking it. Fix this by ensuring +we drop the ref count before returning the error. + +Fixes: 751a27615dda ("btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr()") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 81735d19feff5..362df6e96717c 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -4599,9 +4599,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + if (btrfs_header_nritems(leaf) == 0) { + path->slots[1] = slot; + ret = btrfs_del_leaf(trans, root, path, leaf); ++ free_extent_buffer(leaf); + if (ret < 0) + return ret; +- free_extent_buffer(leaf); + ret = 0; + } else { + /* if we're still in the path, make sure +-- +2.51.0 + diff --git a/queue-6.12/clk-keystone-fix-compile-testing.patch b/queue-6.12/clk-keystone-fix-compile-testing.patch new file mode 100644 index 0000000000..3effc4db6f --- /dev/null +++ b/queue-6.12/clk-keystone-fix-compile-testing.patch @@ -0,0 +1,41 @@ +From 8b06fbeb2aa5cfa655e66aa65cb2f3a55852108d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:53:25 +0100 +Subject: clk: keystone: fix compile testing + +From: Johan Hovold + +[ Upstream commit b276445e98fe28609688fb85b89a81b803910e63 ] + +Some keystone clock drivers can be selected when COMPILE_TEST is +enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk +driver support") they are never actually built. + +Enable compile testing by allowing the build system to process the +keystone drivers. + +Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") +Signed-off-by: Johan Hovold +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/Makefile | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index fb8878a5d7d93..db202b614017e 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -106,8 +106,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ + obj-y += imgtec/ + obj-y += imx/ + obj-y += ingenic/ +-obj-$(CONFIG_ARCH_K3) += keystone/ +-obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ ++obj-y += keystone/ + obj-y += mediatek/ + obj-$(CONFIG_ARCH_MESON) += meson/ + obj-y += microchip/ +-- +2.51.0 + diff --git a/queue-6.12/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch b/queue-6.12/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..e02e7f889b --- /dev/null +++ b/queue-6.12/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch @@ -0,0 +1,53 @@ +From 8d0835895b14486c37d809f8dda28876fa02b721 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:54 +0200 +Subject: clk: qcom: camcc-sm6350: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit ab0e13141d679fdffdd3463a272c5c1b10be1794 ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly, and fixes +CAMCC_MCLK* being stuck off. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 454763425f611..9a62228c314c1 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -144,15 +144,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, + .alpha = 0x0, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), +- .early_output_mask = BIT(3), + .config_ctl_val = 0x20000800, + .config_ctl_hi_val = 0x400003d2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x00004000, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.12/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch b/queue-6.12/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..c9d7068c9f --- /dev/null +++ b/queue-6.12/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,89 @@ +From 9fae947a865c633546333bdedeb1d5aab34212da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:46 +0300 +Subject: clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit a76ce61d7225934b0a52c8172a8cd944002a8c6f ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM6350 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 418668184ec35..454763425f611 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -1692,6 +1692,8 @@ static struct clk_branch camcc_sys_tmr_clk = { + }, + }; + ++static struct gdsc titan_top_gdsc; ++ + static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .en_rest_wait_val = 0x2, +@@ -1701,6 +1703,7 @@ static struct gdsc bps_gdsc = { + .name = "bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1713,6 +1716,7 @@ static struct gdsc ipe_0_gdsc = { + .name = "ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1725,6 +1729,7 @@ static struct gdsc ife_0_gdsc = { + .name = "ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_1_gdsc = { +@@ -1736,6 +1741,7 @@ static struct gdsc ife_1_gdsc = { + .name = "ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_2_gdsc = { +@@ -1747,6 +1753,7 @@ static struct gdsc ife_2_gdsc = { + .name = "ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc titan_top_gdsc = { +-- +2.51.0 + diff --git a/queue-6.12/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch b/queue-6.12/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..742639a264 --- /dev/null +++ b/queue-6.12/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch @@ -0,0 +1,50 @@ +From 815163f7d8937df082f407a506cb9e6038cc41ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:55 +0200 +Subject: clk: qcom: camcc-sm7150: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit 415aad75c7e5cdb72e0672dc1159be1a99535ecd ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly. + +Fixes: 9f0532da4226 ("clk: qcom: Add Camera Clock Controller driver for SM7150") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-2-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm7150.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c +index 39033a6bb6160..ca0078428cb01 100644 +--- a/drivers/clk/qcom/camcc-sm7150.c ++++ b/drivers/clk/qcom/camcc-sm7150.c +@@ -140,13 +140,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = { + /* 1920MHz configuration */ + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .early_output_mask = BIT(3), +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), + .config_ctl_hi_val = 0x400003d6, + .config_ctl_val = 0x20000954, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.12/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch b/queue-6.12/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..a1c9d8d022 --- /dev/null +++ b/queue-6.12/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,113 @@ +From 7a3e8e1b4e6287e15a7a5f5f6c7eba25485e6d9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:45 +0300 +Subject: clk: qcom: camcc-sm8550: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit d8f1121ebf4036884fc9ab1968f606523dd1c1fe ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM8550 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: ccc4e6a061a2 ("clk: qcom: camcc-sm8550: Add camera clock controller driver for SM8550") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-2-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm8550.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c +index eac850bb690a2..caf69526fd710 100644 +--- a/drivers/clk/qcom/camcc-sm8550.c ++++ b/drivers/clk/qcom/camcc-sm8550.c +@@ -3192,6 +3192,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { + }, + }; + ++static struct gdsc cam_cc_titan_top_gdsc; ++ + static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, +@@ -3201,6 +3203,7 @@ static struct gdsc cam_cc_bps_gdsc = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3213,6 +3216,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3225,6 +3229,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3237,6 +3242,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { + .name = "cam_cc_ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3249,6 +3255,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3261,6 +3268,7 @@ static struct gdsc cam_cc_sbi_gdsc = { + .name = "cam_cc_sbi_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3273,6 +3281,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { + .name = "cam_cc_sfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3285,6 +3294,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = { + .name = "cam_cc_sfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +-- +2.51.0 + diff --git a/queue-6.12/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch b/queue-6.12/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch new file mode 100644 index 0000000000..f812eb712f --- /dev/null +++ b/queue-6.12/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch @@ -0,0 +1,1100 @@ +From 5c892b12982e1efafd7dfcfb1ca8b853fe0c2944 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:14:39 +0200 +Subject: clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets + +From: Konrad Dybcio + +[ Upstream commit 8abe970efea56f44773713cf91032cd2fd4d8c01 ] + +Currently, some of the USB4 clocks/resets are described, but not all +of the back-end muxes are present. Configuring them properly is +necessary for proper operation of the hardware. + +Add all the resets & muxes and wire up any unaccounted USB4 clock paths. + +Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Konrad Dybcio +Reviewed-by: Taniya Das +Reviewed-by: Abel Vesa +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251003-topic-hamoa_gcc_usb4-v2-2-61d27a14ee65@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-x1e80100.c | 698 +++++++++++++++++++++++++++++++- + 1 file changed, 681 insertions(+), 17 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c +index 3e44757e25d32..86cc8ecf16a48 100644 +--- a/drivers/clk/qcom/gcc-x1e80100.c ++++ b/drivers/clk/qcom/gcc-x1e80100.c +@@ -32,6 +32,33 @@ enum { + DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE, + DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE, + DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE, ++ DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_QUSB4PHY_0_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_0_GCC_USB4_RX1_CLK, ++ DT_QUSB4PHY_1_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_1_GCC_USB4_RX1_CLK, ++ DT_QUSB4PHY_2_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_2_GCC_USB4_RX1_CLK, ++ DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + }; + + enum { +@@ -42,10 +69,40 @@ enum { + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL8_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, ++ P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, ++ P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, ++ P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, ++ P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_QUSB4PHY_0_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_0_GCC_USB4_RX1_CLK, ++ P_QUSB4PHY_1_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_1_GCC_USB4_RX1_CLK, ++ P_QUSB4PHY_2_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_2_GCC_USB4_RX1_CLK, + P_SLEEP_CLK, + P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, ++ P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + }; + + static struct clk_alpha_pll gcc_gpll0 = { +@@ -320,6 +377,342 @@ static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + { } + }; + ++static const struct clk_parent_data gcc_parent_data_13[] = { ++ { .index = DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_14[] = { ++ { .index = DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_15[] = { ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_16[] = { ++ { .index = DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_17[] = { ++ { .index = DT_QUSB4PHY_0_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_18[] = { ++ { .index = DT_QUSB4PHY_0_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_19[] = { ++ { .index = DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_20[] = { ++ { .index = DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_21[] = { ++ { .index = DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_22[] = { ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_23[] = { ++ { .index = DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_24[] = { ++ { .index = DT_QUSB4PHY_1_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_25[] = { ++ { .index = DT_QUSB4PHY_1_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_26[] = { ++ { .index = DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_27[] = { ++ { .index = DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_28[] = { ++ { .index = DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_29[] = { ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_30[] = { ++ { .index = DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_31[] = { ++ { .index = DT_QUSB4PHY_2_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_32[] = { ++ { .index = DT_QUSB4PHY_2_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_33[] = { ++ { .index = DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { ++ .reg = 0x9f06c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_13, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp1_clk_src = { ++ .reg = 0x9f114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_14, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x9f0d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_15, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x9f104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_16, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx0_clk_src = { ++ .reg = 0x9f0ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_17, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx1_clk_src = { ++ .reg = 0x9f0bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_18, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_sys_clk_src = { ++ .reg = 0x9f0e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_19, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp0_clk_src = { ++ .reg = 0x2b06c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_20, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp1_clk_src = { ++ .reg = 0x2b114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_21, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x2b0d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_22, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x2b104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_23, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx0_clk_src = { ++ .reg = 0x2b0ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_24, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx1_clk_src = { ++ .reg = 0x2b0bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_25, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_sys_clk_src = { ++ .reg = 0x2b0e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_26, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp0_clk_src = { ++ .reg = 0x1106c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_27, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp1_clk_src = { ++ .reg = 0x11114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_28, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x110d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_29, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x11104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_30, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx0_clk_src = { ++ .reg = 0x110ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_31, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx1_clk_src = { ++ .reg = 0x110bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_32, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_sys_clk_src = { ++ .reg = 0x110e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_33, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ + static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 16, +@@ -2790,6 +3183,11 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2879,6 +3277,11 @@ static struct clk_branch gcc_pcie_1_pipe_clk = { + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2968,6 +3371,11 @@ static struct clk_branch gcc_pcie_2_pipe_clk = { + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5156,6 +5564,33 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_34[] = { ++ { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_34[] = { ++ { .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_prim_phy_pipe_clk_src = { ++ .reg = 0x39070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_34, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_prim_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_34, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_34), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x39068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5167,7 +5602,7 @@ static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5227,6 +5662,33 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_35[] = { ++ { P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_35[] = { ++ { .hw = &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_sec_phy_pipe_clk_src = { ++ .reg = 0xa1070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_35, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_sec_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_35, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_35), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0xa1068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5238,7 +5700,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5298,6 +5760,33 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_36[] = { ++ { P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_36[] = { ++ { .hw = &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_tert_phy_pipe_clk_src = { ++ .reg = 0xa2070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_36, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_tert_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_36, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_36), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .halt_reg = 0xa2068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5309,7 +5798,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5335,12 +5824,17 @@ static struct clk_branch gcc_usb4_0_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_0_dp0_clk = { + .halt_reg = 0x9f060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5348,12 +5842,17 @@ static struct clk_branch gcc_usb4_0_dp0_clk = { + + static struct clk_branch gcc_usb4_0_dp1_clk = { + .halt_reg = 0x9f108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5385,6 +5884,11 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5398,6 +5902,11 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5405,12 +5914,17 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_0_phy_rx0_clk = { + .halt_reg = 0x9f0b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f0b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5418,12 +5932,17 @@ static struct clk_branch gcc_usb4_0_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_0_phy_rx1_clk = { + .halt_reg = 0x9f0c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f0c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5439,6 +5958,11 @@ static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5470,6 +5994,11 @@ static struct clk_branch gcc_usb4_0_sys_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_sys_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_sys_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5512,12 +6041,17 @@ static struct clk_branch gcc_usb4_1_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_1_dp0_clk = { + .halt_reg = 0x2b060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5525,12 +6059,17 @@ static struct clk_branch gcc_usb4_1_dp0_clk = { + + static struct clk_branch gcc_usb4_1_dp1_clk = { + .halt_reg = 0x2b108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5562,6 +6101,11 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5575,6 +6119,11 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5582,12 +6131,17 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_1_phy_rx0_clk = { + .halt_reg = 0x2b0b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b0b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5595,12 +6149,17 @@ static struct clk_branch gcc_usb4_1_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_1_phy_rx1_clk = { + .halt_reg = 0x2b0c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b0c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5616,6 +6175,11 @@ static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5647,6 +6211,11 @@ static struct clk_branch gcc_usb4_1_sys_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_sys_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_sys_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5689,12 +6258,17 @@ static struct clk_branch gcc_usb4_2_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_2_dp0_clk = { + .halt_reg = 0x11060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x11060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5702,12 +6276,17 @@ static struct clk_branch gcc_usb4_2_dp0_clk = { + + static struct clk_branch gcc_usb4_2_dp1_clk = { + .halt_reg = 0x11108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x11108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5739,6 +6318,11 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5752,6 +6336,11 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5759,12 +6348,17 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_2_phy_rx0_clk = { + .halt_reg = 0x110b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5772,12 +6366,17 @@ static struct clk_branch gcc_usb4_2_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_2_phy_rx1_clk = { + .halt_reg = 0x110c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x110c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5793,6 +6392,11 @@ static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -6483,6 +7087,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB30_TERT_MOCK_UTMI_CLK_SRC] = &gcc_usb30_tert_mock_utmi_clk_src.clkr, + [GCC_USB30_TERT_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_TERT_SLEEP_CLK] = &gcc_usb30_tert_sleep_clk.clkr, ++ [GCC_USB34_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb34_prim_phy_pipe_clk_src.clkr, ++ [GCC_USB34_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb34_sec_phy_pipe_clk_src.clkr, ++ [GCC_USB34_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb34_tert_phy_pipe_clk_src.clkr, + [GCC_USB3_MP_PHY_AUX_CLK] = &gcc_usb3_mp_phy_aux_clk.clkr, + [GCC_USB3_MP_PHY_AUX_CLK_SRC] = &gcc_usb3_mp_phy_aux_clk_src.clkr, + [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, +@@ -6508,11 +7115,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_0_DP1_CLK] = &gcc_usb4_0_dp1_clk.clkr, + [GCC_USB4_0_MASTER_CLK] = &gcc_usb4_0_master_clk.clkr, + [GCC_USB4_0_MASTER_CLK_SRC] = &gcc_usb4_0_master_clk_src.clkr, ++ [GCC_USB4_0_PHY_DP0_CLK_SRC] = &gcc_usb4_0_phy_dp0_clk_src.clkr, ++ [GCC_USB4_0_PHY_DP1_CLK_SRC] = &gcc_usb4_0_phy_dp1_clk_src.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_0_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK] = &gcc_usb4_0_phy_pcie_pipe_clk.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_0_PHY_RX0_CLK] = &gcc_usb4_0_phy_rx0_clk.clkr, ++ [GCC_USB4_0_PHY_RX0_CLK_SRC] = &gcc_usb4_0_phy_rx0_clk_src.clkr, + [GCC_USB4_0_PHY_RX1_CLK] = &gcc_usb4_0_phy_rx1_clk.clkr, ++ [GCC_USB4_0_PHY_RX1_CLK_SRC] = &gcc_usb4_0_phy_rx1_clk_src.clkr, ++ [GCC_USB4_0_PHY_SYS_CLK_SRC] = &gcc_usb4_0_phy_sys_clk_src.clkr, + [GCC_USB4_0_PHY_USB_PIPE_CLK] = &gcc_usb4_0_phy_usb_pipe_clk.clkr, + [GCC_USB4_0_SB_IF_CLK] = &gcc_usb4_0_sb_if_clk.clkr, + [GCC_USB4_0_SB_IF_CLK_SRC] = &gcc_usb4_0_sb_if_clk_src.clkr, +@@ -6524,11 +7138,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_1_DP1_CLK] = &gcc_usb4_1_dp1_clk.clkr, + [GCC_USB4_1_MASTER_CLK] = &gcc_usb4_1_master_clk.clkr, + [GCC_USB4_1_MASTER_CLK_SRC] = &gcc_usb4_1_master_clk_src.clkr, ++ [GCC_USB4_1_PHY_DP0_CLK_SRC] = &gcc_usb4_1_phy_dp0_clk_src.clkr, ++ [GCC_USB4_1_PHY_DP1_CLK_SRC] = &gcc_usb4_1_phy_dp1_clk_src.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_1_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK] = &gcc_usb4_1_phy_pcie_pipe_clk.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_1_PHY_RX0_CLK] = &gcc_usb4_1_phy_rx0_clk.clkr, ++ [GCC_USB4_1_PHY_RX0_CLK_SRC] = &gcc_usb4_1_phy_rx0_clk_src.clkr, + [GCC_USB4_1_PHY_RX1_CLK] = &gcc_usb4_1_phy_rx1_clk.clkr, ++ [GCC_USB4_1_PHY_RX1_CLK_SRC] = &gcc_usb4_1_phy_rx1_clk_src.clkr, ++ [GCC_USB4_1_PHY_SYS_CLK_SRC] = &gcc_usb4_1_phy_sys_clk_src.clkr, + [GCC_USB4_1_PHY_USB_PIPE_CLK] = &gcc_usb4_1_phy_usb_pipe_clk.clkr, + [GCC_USB4_1_SB_IF_CLK] = &gcc_usb4_1_sb_if_clk.clkr, + [GCC_USB4_1_SB_IF_CLK_SRC] = &gcc_usb4_1_sb_if_clk_src.clkr, +@@ -6540,11 +7161,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_2_DP1_CLK] = &gcc_usb4_2_dp1_clk.clkr, + [GCC_USB4_2_MASTER_CLK] = &gcc_usb4_2_master_clk.clkr, + [GCC_USB4_2_MASTER_CLK_SRC] = &gcc_usb4_2_master_clk_src.clkr, ++ [GCC_USB4_2_PHY_DP0_CLK_SRC] = &gcc_usb4_2_phy_dp0_clk_src.clkr, ++ [GCC_USB4_2_PHY_DP1_CLK_SRC] = &gcc_usb4_2_phy_dp1_clk_src.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_2_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK] = &gcc_usb4_2_phy_pcie_pipe_clk.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_2_PHY_RX0_CLK] = &gcc_usb4_2_phy_rx0_clk.clkr, ++ [GCC_USB4_2_PHY_RX0_CLK_SRC] = &gcc_usb4_2_phy_rx0_clk_src.clkr, + [GCC_USB4_2_PHY_RX1_CLK] = &gcc_usb4_2_phy_rx1_clk.clkr, ++ [GCC_USB4_2_PHY_RX1_CLK_SRC] = &gcc_usb4_2_phy_rx1_clk_src.clkr, ++ [GCC_USB4_2_PHY_SYS_CLK_SRC] = &gcc_usb4_2_phy_sys_clk_src.clkr, + [GCC_USB4_2_PHY_USB_PIPE_CLK] = &gcc_usb4_2_phy_usb_pipe_clk.clkr, + [GCC_USB4_2_SB_IF_CLK] = &gcc_usb4_2_sb_if_clk.clkr, + [GCC_USB4_2_SB_IF_CLK_SRC] = &gcc_usb4_2_sb_if_clk_src.clkr, +@@ -6660,16 +7288,52 @@ static const struct qcom_reset_map gcc_x1e80100_resets[] = { + [GCC_USB3_UNIPHY_MP0_BCR] = { 0x19000 }, + [GCC_USB3_UNIPHY_MP1_BCR] = { 0x54000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, ++ [GCC_USB4PHY_PHY_PRIM_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x2a004 }, ++ [GCC_USB4PHY_PHY_SEC_BCR] = { 0x2a00c }, + [GCC_USB3PHY_PHY_TERT_BCR] = { 0xa3004 }, ++ [GCC_USB4PHY_PHY_TERT_BCR] = { 0xa300c }, + [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x19004 }, + [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x54004 }, + [GCC_USB4_0_BCR] = { 0x9f000 }, + [GCC_USB4_0_DP0_PHY_PRIM_BCR] = { 0x50010 }, +- [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, +- [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, ++ [GCC_USB4_0_MISC_USB4_SYS_BCR] = { .reg = 0xad0f8, .bit = 0 }, ++ [GCC_USB4_0_MISC_RX_CLK_0_BCR] = { .reg = 0xad0f8, .bit = 1 }, ++ [GCC_USB4_0_MISC_RX_CLK_1_BCR] = { .reg = 0xad0f8, .bit = 2 }, ++ [GCC_USB4_0_MISC_USB_PIPE_BCR] = { .reg = 0xad0f8, .bit = 3 }, ++ [GCC_USB4_0_MISC_PCIE_PIPE_BCR] = { .reg = 0xad0f8, .bit = 4 }, ++ [GCC_USB4_0_MISC_TMU_BCR] = { .reg = 0xad0f8, .bit = 5 }, ++ [GCC_USB4_0_MISC_SB_IF_BCR] = { .reg = 0xad0f8, .bit = 6 }, ++ [GCC_USB4_0_MISC_HIA_MSTR_BCR] = { .reg = 0xad0f8, .bit = 7 }, ++ [GCC_USB4_0_MISC_AHB_BCR] = { .reg = 0xad0f8, .bit = 8 }, ++ [GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 9 }, ++ [GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 10 }, + [GCC_USB4_1_BCR] = { 0x2b000 }, ++ [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, ++ [GCC_USB4_1_MISC_USB4_SYS_BCR] = { .reg = 0xae0f8, .bit = 0 }, ++ [GCC_USB4_1_MISC_RX_CLK_0_BCR] = { .reg = 0xae0f8, .bit = 1 }, ++ [GCC_USB4_1_MISC_RX_CLK_1_BCR] = { .reg = 0xae0f8, .bit = 2 }, ++ [GCC_USB4_1_MISC_USB_PIPE_BCR] = { .reg = 0xae0f8, .bit = 3 }, ++ [GCC_USB4_1_MISC_PCIE_PIPE_BCR] = { .reg = 0xae0f8, .bit = 4 }, ++ [GCC_USB4_1_MISC_TMU_BCR] = { .reg = 0xae0f8, .bit = 5 }, ++ [GCC_USB4_1_MISC_SB_IF_BCR] = { .reg = 0xae0f8, .bit = 6 }, ++ [GCC_USB4_1_MISC_HIA_MSTR_BCR] = { .reg = 0xae0f8, .bit = 7 }, ++ [GCC_USB4_1_MISC_AHB_BCR] = { .reg = 0xae0f8, .bit = 8 }, ++ [GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 9 }, ++ [GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 10 }, + [GCC_USB4_2_BCR] = { 0x11000 }, ++ [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, ++ [GCC_USB4_2_MISC_USB4_SYS_BCR] = { .reg = 0xaf0f8, .bit = 0 }, ++ [GCC_USB4_2_MISC_RX_CLK_0_BCR] = { .reg = 0xaf0f8, .bit = 1 }, ++ [GCC_USB4_2_MISC_RX_CLK_1_BCR] = { .reg = 0xaf0f8, .bit = 2 }, ++ [GCC_USB4_2_MISC_USB_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 3 }, ++ [GCC_USB4_2_MISC_PCIE_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 4 }, ++ [GCC_USB4_2_MISC_TMU_BCR] = { .reg = 0xaf0f8, .bit = 5 }, ++ [GCC_USB4_2_MISC_SB_IF_BCR] = { .reg = 0xaf0f8, .bit = 6 }, ++ [GCC_USB4_2_MISC_HIA_MSTR_BCR] = { .reg = 0xaf0f8, .bit = 7 }, ++ [GCC_USB4_2_MISC_AHB_BCR] = { .reg = 0xaf0f8, .bit = 8 }, ++ [GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 9 }, ++ [GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 10 }, + [GCC_USB_0_PHY_BCR] = { 0x50020 }, + [GCC_USB_1_PHY_BCR] = { 0x2a020 }, + [GCC_USB_2_PHY_BCR] = { 0xa3020 }, +-- +2.51.0 + diff --git a/queue-6.12/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch b/queue-6.12/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch new file mode 100644 index 0000000000..e7474dd6f4 --- /dev/null +++ b/queue-6.12/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch @@ -0,0 +1,58 @@ +From 902fc2090e25a8f560b771d031c8ea732504e501 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 05:04:43 +0200 +Subject: clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle + callback + +From: Marek Vasut + +[ Upstream commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab ] + +R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page +583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) +indicate after reset has been asserted by writing a matching reset bit +into register SRCR, it is mandatory to wait 1ms. + +This 1ms delay is documented on R-Car V4H and V4M, it is currently +unclear whether S4 is affected as well. This patch does apply the extra +delay on R-Car S4 as well. + +Fix the reset driver to respect the additional delay when toggling +resets. Drivers which use separate reset_control_(de)assert() must +assure matching delay in their driver code. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 112ed81f648ee..ecb7e2024d589 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -630,8 +630,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + /* Reset module */ + writel(bitmask, priv->base + priv->reset_regs[reg]); + +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); ++ /* ++ * On R-Car Gen4, delay after SRCR has been written is 1ms. ++ * On older SoCs, delay after SRCR has been written is 35us ++ * (one cycle of the RCLK clock @ ca. 32 kHz). ++ */ ++ if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) ++ usleep_range(1000, 2000); ++ else ++ usleep_range(35, 1000); + + /* Release module from reset state */ + writel(bitmask, priv->base + priv->reset_clear_regs[reg]); +-- +2.51.0 + diff --git a/queue-6.12/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch b/queue-6.12/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch new file mode 100644 index 0000000000..9566e4f27a --- /dev/null +++ b/queue-6.12/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch @@ -0,0 +1,124 @@ +From 8a97dbd73e7fbb3aa8093916d28fce81a3c74847 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 18:20:38 +0200 +Subject: clk: renesas: cpg-mssr: Read back reset registers to assure values + latched + +From: Marek Vasut + +[ Upstream commit b91401af6c00ffab003698bfabd4c166df30748b ] + +On R-Car V4H, the PCIEC controller DBI read would generate an SError in +case the controller reset is released by writing SRSTCLR register first, +and immediately afterward reading some PCIEC controller DBI register. +The issue triggers in rcar_gen4_pcie_additional_common_init() on +dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first +read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). + +The reset controller which contains the SRSTCLR register and the PCIEC +controller which contains the DBI register share the same root access +bus, but the bus then splits into separate segments before reaching each +IP. Even if the SRSTCLR write access was posted on the bus before the +DBI read access, it seems the DBI read access may reach the PCIEC +controller before the SRSTCLR write completed, and trigger the SError. + +Mitigate the issue by adding a dummy SRSTCLR read, which assures the +SRSTCLR write completes fully and is latched into the reset controller, +before the PCIEC DBI read access can occur. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Reviewed-by: Wolfram Sang +Tested-by: Geert Uytterhoeven +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 291a01778aa48..e0f0dc8c0e56d 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -615,18 +615,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, + + #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) + +-static int cpg_mssr_reset(struct reset_controller_dev *rcdev, +- unsigned long id) ++static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, ++ const char *func, bool set, unsigned long id) + { + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + unsigned int reg = id / 32; + unsigned int bit = id % 32; ++ const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; + u32 bitmask = BIT(bit); + +- dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); ++ if (func) ++ dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); ++ ++ writel(bitmask, priv->pub.base0 + off); ++ readl(priv->pub.base0 + off); ++ barrier_data(priv->pub.base0 + off); ++ ++ return 0; ++} ++ ++static int cpg_mssr_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + + /* Reset module */ +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); ++ cpg_mssr_reset_operate(rcdev, "reset", true, id); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -639,36 +653,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- +- return 0; ++ return cpg_mssr_reset_operate(rcdev, NULL, false, id); + } + + static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "assert", true, id); + } + + static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "deassert", false, id); + } + + static int cpg_mssr_status(struct reset_controller_dev *rcdev, +-- +2.51.0 + diff --git a/queue-6.12/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch b/queue-6.12/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch new file mode 100644 index 0000000000..e04c856cc8 --- /dev/null +++ b/queue-6.12/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch @@ -0,0 +1,554 @@ +From 3668c9717166dab420f944d200e609ab328b7ba0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 May 2025 16:18:19 +0200 +Subject: clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register + +From: Thierry Bultel + +[ Upstream commit 3d37ca1482c36975255f29911a529f84f1bc34a9 ] + +In a subsequent patch, the registration callback will need more parameters +from cpg_mssr_priv (like another base address with clock controllers +with double register block, and also, notifiers and rmw_lock). +Instead of adding more parameters, move the needed parameters to a public +sub-struct. +Instead moving clks to this structure, which would have implied to add +an allocation (and cleanup) for it, keep the way the allocation is done +and just have a copy of the pointer in the public structure. + +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Thierry Bultel +Link: https://lore.kernel.org/20250515141828.43444-5-thierry.bultel.yh@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r7s9210-cpg-mssr.c | 7 +- + drivers/clk/renesas/r8a77970-cpg-mssr.c | 8 +- + drivers/clk/renesas/rcar-gen2-cpg.c | 5 +- + drivers/clk/renesas/rcar-gen2-cpg.h | 3 +- + drivers/clk/renesas/rcar-gen3-cpg.c | 6 +- + drivers/clk/renesas/rcar-gen3-cpg.h | 3 +- + drivers/clk/renesas/rcar-gen4-cpg.c | 6 +- + drivers/clk/renesas/rcar-gen4-cpg.h | 3 +- + drivers/clk/renesas/renesas-cpg-mssr.c | 98 ++++++++++++------------- + drivers/clk/renesas/renesas-cpg-mssr.h | 20 ++++- + 10 files changed, 88 insertions(+), 71 deletions(-) + +diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c +index a85227c248f31..733244687daa8 100644 +--- a/drivers/clk/renesas/r7s9210-cpg-mssr.c ++++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c +@@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk, + + static struct clk * __init rza2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { +- struct clk *parent; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + unsigned int mult = 1; + unsigned int div = 1; ++ struct clk *parent; + + parent = clks[core->parent]; + if (IS_ERR(parent)) +diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c +index 3cec0f501b947..e2bda2c107306 100644 +--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c +@@ -219,10 +219,11 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev) + + static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { + const struct clk_div_table *table; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int shift; + +@@ -236,8 +237,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, + shift = 4; + break; + default: +- return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, +- notifiers); ++ return rcar_gen3_cpg_clk_register(dev, core, info, pub); + } + + parent = clks[core->parent]; +diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c +index 4c3764972bad9..ab34bb8c3e079 100644 +--- a/drivers/clk/renesas/rcar-gen2-cpg.c ++++ b/drivers/clk/renesas/rcar-gen2-cpg.c +@@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { + + struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { + const struct clk_div_table *table = NULL; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + const char *parent_name; + unsigned int mult = 1; +diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h +index bdcd4a38d48d0..3d4b127fdeaf4 100644 +--- a/drivers/clk/renesas/rcar-gen2-cpg.h ++++ b/drivers/clk/renesas/rcar-gen2-cpg.h +@@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config { + + struct clk *rcar_gen2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config, + unsigned int pll0_div, u32 mode); + +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c +index 20b89eb6c35c1..1766d77adefcb 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.c ++++ b/drivers/clk/renesas/rcar-gen3-cpg.c +@@ -346,9 +346,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { + + struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { ++ struct raw_notifier_head *notifiers = &pub->notifiers; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h +index bfdc649bdf12c..d15a5d1df71c7 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.h ++++ b/drivers/clk/renesas/rcar-gen3-cpg.h +@@ -81,8 +81,7 @@ struct rcar_gen3_cpg_pll_config { + + struct clk *rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, + unsigned int clk_extalr, u32 mode); + +diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c +index 31aa790fd003d..fb9a876aaba5c 100644 +--- a/drivers/clk/renesas/rcar-gen4-cpg.c ++++ b/drivers/clk/renesas/rcar-gen4-cpg.c +@@ -418,9 +418,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = { + + struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { ++ struct raw_notifier_head *notifiers = &pub->notifiers; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; +diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h +index 717fd148464fe..6c8280b37c37b 100644 +--- a/drivers/clk/renesas/rcar-gen4-cpg.h ++++ b/drivers/clk/renesas/rcar-gen4-cpg.h +@@ -78,8 +78,7 @@ struct rcar_gen4_cpg_pll_config { + + struct clk *rcar_gen4_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config, + unsigned int clk_extalr, u32 mode); + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 22699a47e675c..291a01778aa48 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -127,16 +127,14 @@ static const u16 srstclr_for_gen4[] = { + * struct cpg_mssr_priv - Clock Pulse Generator / Module Standby + * and Software Reset Private Data + * ++ * @pub: Data passed to clock registration callback + * @rcdev: Optional reset controller entity + * @dev: CPG/MSSR device +- * @base: CPG/MSSR register block base address + * @reg_layout: CPG/MSSR register layout +- * @rmw_lock: protects RMW register accesses + * @np: Device node in DT for this CPG/MSSR module + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT +- * @notifiers: Notifier chain to save/restore clock state for system resume + * @status_regs: Pointer to status registers array + * @control_regs: Pointer to control registers array + * @reset_regs: Pointer to reset registers array +@@ -148,20 +146,18 @@ static const u16 srstclr_for_gen4[] = { + * @clks: Array containing all Core and Module Clocks + */ + struct cpg_mssr_priv { ++ struct cpg_mssr_pub pub; + #ifdef CONFIG_RESET_CONTROLLER + struct reset_controller_dev rcdev; + #endif + struct device *dev; +- void __iomem *base; + enum clk_reg_layout reg_layout; +- spinlock_t rmw_lock; + struct device_node *np; + + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int last_dt_core_clk; + +- struct raw_notifier_head notifiers; + const u16 *status_regs; + const u16 *control_regs; + const u16 *reset_regs; +@@ -207,38 +203,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, + str_on_off(enable)); +- spin_lock_irqsave(&priv->rmw_lock, flags); ++ spin_lock_irqsave(&priv->pub.rmw_lock, flags); + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +- value = readb(priv->base + priv->control_regs[reg]); ++ value = readb(priv->pub.base0 + priv->control_regs[reg]); + if (enable) + value &= ~bitmask; + else + value |= bitmask; +- writeb(value, priv->base + priv->control_regs[reg]); ++ writeb(value, priv->pub.base0 + priv->control_regs[reg]); + + /* dummy read to ensure write has completed */ +- readb(priv->base + priv->control_regs[reg]); +- barrier_data(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]); ++ barrier_data(priv->pub.base0 + priv->control_regs[reg]); ++ + } else { +- value = readl(priv->base + priv->control_regs[reg]); ++ value = readl(priv->pub.base0 + priv->control_regs[reg]); + if (enable) + value &= ~bitmask; + else + value |= bitmask; +- writel(value, priv->base + priv->control_regs[reg]); ++ writel(value, priv->pub.base0 + priv->control_regs[reg]); + } + +- spin_unlock_irqrestore(&priv->rmw_lock, flags); ++ spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + return 0; + +- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], ++ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], + value, !(value & bitmask), 0, 10); + if (error) + dev_err(dev, "Failed to enable SMSTP %p[%d]\n", +- priv->base + priv->control_regs[reg], bit); ++ priv->pub.base0 + priv->control_regs[reg], bit); + + return error; + } +@@ -257,12 +254,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) + { + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; ++ unsigned int reg = clock->index / 32; + u32 value; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) +- value = readb(priv->base + priv->control_regs[clock->index / 32]); ++ value = readb(priv->pub.base0 + priv->control_regs[reg]); + else +- value = readl(priv->base + priv->status_regs[clock->index / 32]); ++ value = readl(priv->pub.base0 + priv->status_regs[reg]); + + return !(value & BIT(clock->index % 32)); + } +@@ -354,7 +352,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + case CLK_TYPE_DIV6P1: + case CLK_TYPE_DIV6_RO: + WARN_DEBUG(core->parent >= priv->num_core_clks); +- parent = priv->clks[core->parent]; ++ parent = priv->pub.clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; +@@ -364,12 +362,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + + if (core->type == CLK_TYPE_DIV6_RO) + /* Multiply with the DIV6 register value */ +- div *= (readl(priv->base + core->offset) & 0x3f) + 1; ++ div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1; + + if (core->type == CLK_TYPE_DIV6P1) { + clk = cpg_div6_register(core->name, 1, &parent_name, +- priv->base + core->offset, +- &priv->notifiers); ++ priv->pub.base0 + core->offset, ++ &priv->pub.notifiers); + } else { + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, 0, +@@ -385,8 +383,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + default: + if (info->cpg_clk_register) + clk = info->cpg_clk_register(dev, core, info, +- priv->clks, priv->base, +- &priv->notifiers); ++ &priv->pub); + else + dev_err(dev, "%s has unsupported core clock type %u\n", + core->name, core->type); +@@ -397,7 +394,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + goto fail; + + dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); +- priv->clks[id] = clk; ++ priv->pub.clks[id] = clk; + return; + + fail: +@@ -420,14 +417,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); +- WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); ++ WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT); + + if (!mod->name) { + /* Skip NULLified clock */ + return; + } + +- parent = priv->clks[mod->parent]; ++ parent = priv->pub.clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; +@@ -629,7 +626,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); + + /* Reset module */ +- writel(bitmask, priv->base + priv->reset_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -642,7 +639,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->base + priv->reset_clear_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); + + return 0; + } +@@ -656,7 +653,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + + dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); + +- writel(bitmask, priv->base + priv->reset_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + return 0; + } + +@@ -670,7 +667,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + + dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); + +- writel(bitmask, priv->base + priv->reset_clear_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); + return 0; + } + +@@ -682,7 +679,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev, + unsigned int bit = id % 32; + u32 bitmask = BIT(bit); + +- return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask); ++ return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); + } + + static const struct reset_control_ops cpg_mssr_reset_ops = { +@@ -909,12 +906,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev) + if (priv->smstpcr_saved[reg].mask) + priv->smstpcr_saved[reg].val = + priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? +- readb(priv->base + priv->control_regs[reg]) : +- readl(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]) : ++ readl(priv->pub.base0 + priv->control_regs[reg]); + } + + /* Save core clocks */ +- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL); ++ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL); + + return 0; + } +@@ -931,7 +928,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) + return 0; + + /* Restore core clocks */ +- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL); ++ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL); + + /* Restore module clocks */ + for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { +@@ -940,29 +937,29 @@ static int cpg_mssr_resume_noirq(struct device *dev) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) +- oldval = readb(priv->base + priv->control_regs[reg]); ++ oldval = readb(priv->pub.base0 + priv->control_regs[reg]); + else +- oldval = readl(priv->base + priv->control_regs[reg]); ++ oldval = readl(priv->pub.base0 + priv->control_regs[reg]); + newval = oldval & ~mask; + newval |= priv->smstpcr_saved[reg].val & mask; + if (newval == oldval) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +- writeb(newval, priv->base + priv->control_regs[reg]); ++ writeb(newval, priv->pub.base0 + priv->control_regs[reg]); + /* dummy read to ensure write has completed */ +- readb(priv->base + priv->control_regs[reg]); +- barrier_data(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]); ++ barrier_data(priv->pub.base0 + priv->control_regs[reg]); + continue; + } else +- writel(newval, priv->base + priv->control_regs[reg]); ++ writel(newval, priv->pub.base0 + priv->control_regs[reg]); + + /* Wait until enabled clocks are really enabled */ + mask &= ~priv->smstpcr_saved[reg].val; + if (!mask) + continue; + +- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], ++ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], + oldval, !(oldval & mask), 0, 10); + if (error) + dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, +@@ -1075,12 +1072,13 @@ static int __init cpg_mssr_common_init(struct device *dev, + if (!priv) + return -ENOMEM; + ++ priv->pub.clks = priv->clks; + priv->np = np; + priv->dev = dev; +- spin_lock_init(&priv->rmw_lock); ++ spin_lock_init(&priv->pub.rmw_lock); + +- priv->base = of_iomap(np, 0); +- if (!priv->base) { ++ priv->pub.base0 = of_iomap(np, 0); ++ if (!priv->pub.base0) { + error = -ENOMEM; + goto out_err; + } +@@ -1088,7 +1086,7 @@ static int __init cpg_mssr_common_init(struct device *dev, + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->last_dt_core_clk = info->last_dt_core_clk; +- RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); ++ RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers); + priv->reg_layout = info->reg_layout; + if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) { + priv->status_regs = mstpsr; +@@ -1108,7 +1106,7 @@ static int __init cpg_mssr_common_init(struct device *dev, + } + + for (i = 0; i < nclks; i++) +- priv->clks[i] = ERR_PTR(-ENOENT); ++ priv->pub.clks[i] = ERR_PTR(-ENOENT); + + error = cpg_mssr_reserved_init(priv, info); + if (error) +@@ -1125,8 +1123,8 @@ static int __init cpg_mssr_common_init(struct device *dev, + reserve_err: + cpg_mssr_reserved_exit(priv); + out_err: +- if (priv->base) +- iounmap(priv->base); ++ if (priv->pub.base0) ++ iounmap(priv->pub.base0); + kfree(priv); + + return error; +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h +index a1d6e0cbcff94..7ce3cc9a64c1e 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.h ++++ b/drivers/clk/renesas/renesas-cpg-mssr.h +@@ -8,6 +8,8 @@ + #ifndef __CLK_RENESAS_CPG_MSSR_H__ + #define __CLK_RENESAS_CPG_MSSR_H__ + ++#include ++ + /* + * Definitions of CPG Core Clocks + * +@@ -29,6 +31,21 @@ struct cpg_core_clk { + unsigned int offset; + }; + ++/** ++ * struct cpg_mssr_pub - data shared with device-specific clk registration code ++ * ++ * @base0: CPG/MSSR register block base0 address ++ * @notifiers: Notifier chain to save/restore clock state for system resume ++ * @rmw_lock: protects RMW register accesses ++ * @clks: pointer to clocks ++ */ ++struct cpg_mssr_pub { ++ void __iomem *base0; ++ struct raw_notifier_head notifiers; ++ spinlock_t rmw_lock; ++ struct clk **clks; ++}; ++ + enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ +@@ -153,8 +170,7 @@ struct cpg_mssr_info { + struct clk *(*cpg_clk_register)(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + }; + + extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; +-- +2.51.0 + diff --git a/queue-6.12/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-6.12/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..dde626f07a --- /dev/null +++ b/queue-6.12/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 13deb0f46c991c98e60342a0e6ca5cfdbf82fb94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index c1348e2d450cd..720e4331ed72c 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -1318,9 +1318,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-6.12/clk-renesas-use-str_on_off-helper.patch b/queue-6.12/clk-renesas-use-str_on_off-helper.patch new file mode 100644 index 0000000000..eee4cabe1f --- /dev/null +++ b/queue-6.12/clk-renesas-use-str_on_off-helper.patch @@ -0,0 +1,67 @@ +From c1472b15d8308f978c8cd19cb0f5f7666f6c06e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 13:45:55 +0200 +Subject: clk: renesas: Use str_on_off() helper + +From: Geert Uytterhoeven + +[ Upstream commit aff664cc8cbc5c28e5aa57dc4201c34497f3c871 ] + +Use the str_on_off() helper instead of open-coding the same operation. +Note that this does change the case of the flags, which doesn't matter +much for debug messages. + +Signed-off-by: Geert Uytterhoeven +Link: https://lore.kernel.org/622f8554dcb815c8fc73511a1a118c1724570fa9.1745840497.git.geert+renesas@glider.be +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- + drivers/clk/renesas/rzg2l-cpg.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index ecb7e2024d589..22699a47e675c 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include + +@@ -205,7 +206,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) + int error; + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, +- enable ? "ON" : "OFF"); ++ str_on_off(enable)); + spin_lock_irqsave(&priv->rmw_lock, flags); + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index e2ecc9d36e051..e4f2d974f38a1 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -1222,7 +1223,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + } + + dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, +- enable ? "ON" : "OFF"); ++ str_on_off(enable)); + + value = bitmask << 16; + if (enable) +-- +2.51.0 + diff --git a/queue-6.12/coresight-change-device-mode-to-atomic-type.patch b/queue-6.12/coresight-change-device-mode-to-atomic-type.patch new file mode 100644 index 0000000000..393192761c --- /dev/null +++ b/queue-6.12/coresight-change-device-mode-to-atomic-type.patch @@ -0,0 +1,91 @@ +From 53a7cc7e2694dee0b8b92e9f6de4b74c4b7d52fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:35 +0000 +Subject: coresight: Change device mode to atomic type + +From: Leo Yan + +[ Upstream commit 693d1eaca940f277af24c74873ef2313816ff444 ] + +The device mode is defined as local type. This type cannot promise +SMP-safe access. + +Change to atomic type and impose relax ordering, which ensures the +SMP-safe synchronisation and the ordering between the mode setting and +relevant operations. + +Fixes: 22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()") +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-1-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + include/linux/coresight.h | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index 59f99b7da43f5..0165a0b403cb9 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -245,15 +245,11 @@ struct coresight_trace_id_map { + * by @coresight_ops. + * @access: Device i/o access abstraction for this device. + * @dev: The device entity associated to this component. +- * @mode: This tracer's mode, i.e sysFS, Perf or disabled. This is +- * actually an 'enum cs_mode', but is stored in an atomic type. +- * This is always accessed through local_read() and local_set(), +- * but wherever it's done from within the Coresight device's lock, +- * a non-atomic read would also work. This is the main point of +- * synchronisation between code happening inside the sysfs mode's +- * coresight_mutex and outside when running in Perf mode. A compare +- * and exchange swap is done to atomically claim one mode or the +- * other. ++ * @mode: The device mode, i.e sysFS, Perf or disabled. This is actually ++ * an 'enum cs_mode' but stored in an atomic type. Access is always ++ * through atomic APIs, ensuring SMP-safe synchronisation between ++ * racing from sysFS and Perf mode. A compare-and-exchange ++ * operation is done to atomically claim one mode or the other. + * @refcnt: keep track of what is in use. Only access this outside of the + * device's spinlock when the coresight_mutex held and mode == + * CS_MODE_SYSFS. Otherwise it must be accessed from inside the +@@ -282,7 +278,7 @@ struct coresight_device { + const struct coresight_ops *ops; + struct csdev_access access; + struct device dev; +- local_t mode; ++ atomic_t mode; + int refcnt; + bool orphan; + /* sink specific fields */ +@@ -607,13 +603,14 @@ static inline bool coresight_is_percpu_sink(struct coresight_device *csdev) + static inline bool coresight_take_mode(struct coresight_device *csdev, + enum cs_mode new_mode) + { +- return local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, new_mode) == +- CS_MODE_DISABLED; ++ int curr = CS_MODE_DISABLED; ++ ++ return atomic_try_cmpxchg_acquire(&csdev->mode, &curr, new_mode); + } + + static inline enum cs_mode coresight_get_mode(struct coresight_device *csdev) + { +- return local_read(&csdev->mode); ++ return atomic_read_acquire(&csdev->mode); + } + + static inline void coresight_set_mode(struct coresight_device *csdev, +@@ -629,7 +626,7 @@ static inline void coresight_set_mode(struct coresight_device *csdev, + WARN(new_mode != CS_MODE_DISABLED && current_mode != CS_MODE_DISABLED && + current_mode != new_mode, "Device already in use\n"); + +- local_set(&csdev->mode, new_mode); ++ atomic_set_release(&csdev->mode, new_mode); + } + + extern struct coresight_device * +-- +2.51.0 + diff --git a/queue-6.12/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-6.12/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..41d16ad523 --- /dev/null +++ b/queue-6.12/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From 2a6e496b1bb3b906fe4abe986047ca6a1699a3bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 853a170439608..730ba893bf4cd 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -436,10 +436,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -919,11 +933,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-6.12/coresight-etm4x-correct-polling-idle-bit.patch b/queue-6.12/coresight-etm4x-correct-polling-idle-bit.patch new file mode 100644 index 0000000000..c973c012a4 --- /dev/null +++ b/queue-6.12/coresight-etm4x-correct-polling-idle-bit.patch @@ -0,0 +1,43 @@ +From 3ae0ef5f64ddbb0ed07266f8e0f24afd687a3722 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:38 +0000 +Subject: coresight: etm4x: Correct polling IDLE bit + +From: Leo Yan + +[ Upstream commit 4dc4e22f9536341255f5de6047977a80ff47eaef ] + +Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading +the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit +instead of the IDLE bit. + +This commit corrects the typo. + +Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") +Reviewed-by: Yeoreum Yun +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 7b9eaeb115d21..9164e134814ae 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1844,7 +1844,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +-- +2.51.0 + diff --git a/queue-6.12/coresight-etm4x-extract-the-trace-unit-controlling.patch b/queue-6.12/coresight-etm4x-extract-the-trace-unit-controlling.patch new file mode 100644 index 0000000000..a96ded2038 --- /dev/null +++ b/queue-6.12/coresight-etm4x-extract-the-trace-unit-controlling.patch @@ -0,0 +1,171 @@ +From 5805443270c856a4c8f3f600be1c6e02f0b21a40 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 19:07:02 +0100 +Subject: coresight: etm4x: Extract the trace unit controlling + +From: Leo Yan + +[ Upstream commit 40f682ae5086366d51e29e66eb8a344501245d0d ] + +The trace unit is controlled in the ETM hardware enabling and disabling. +The sequential changes for support AUX pause and resume will reuse the +same operations. + +Extract the operations in the etm4_{enable|disable}_trace_unit() +functions. A minor improvement in etm4_enable_trace_unit() is for +returning the timeout error to callers. + +Signed-off-by: Leo Yan +Reviewed-by: Mike Leach +Reviewed-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250401180708.385396-2-leo.yan@arm.com +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 103 +++++++++++------- + 1 file changed, 62 insertions(+), 41 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 9164e134814ae..853a170439608 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -422,6 +422,44 @@ static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) + return coresight_timeout(csa, TRCSTATR, pos, val); + } + ++static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) ++{ ++ struct coresight_device *csdev = drvdata->csdev; ++ struct device *etm_dev = &csdev->dev; ++ struct csdev_access *csa = &csdev->access; ++ ++ /* ++ * ETE mandates that the TRCRSR is written to before ++ * enabling it. ++ */ ++ if (etm4x_is_ete(drvdata)) ++ etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); ++ ++ etm4x_allow_trace(drvdata); ++ /* Enable the trace unit */ ++ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); ++ ++ /* Synchronize the register updates for sysreg access */ ++ if (!csa->io_mem) ++ isb(); ++ ++ /* wait for TRCSTATR.IDLE to go back down to '0' */ ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) { ++ dev_err(etm_dev, ++ "timeout while waiting for Idle Trace Status\n"); ++ return -ETIME; ++ } ++ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using the ++ * memory-mapped interface") of ARM IHI 0064D ++ */ ++ dsb(sy); ++ isb(); ++ ++ return 0; ++} ++ + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + { + int i, rc; +@@ -531,33 +569,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); + } + +- /* +- * ETE mandates that the TRCRSR is written to before +- * enabling it. +- */ +- if (etm4x_is_ete(drvdata)) +- etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); +- +- etm4x_allow_trace(drvdata); +- /* Enable the trace unit */ +- etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); +- +- /* Synchronize the register updates for sysreg access */ +- if (!csa->io_mem) +- isb(); +- +- /* wait for TRCSTATR.IDLE to go back down to '0' */ +- if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) +- dev_err(etm_dev, +- "timeout while waiting for Idle Trace Status\n"); +- +- /* +- * As recommended by section 4.3.7 ("Synchronization when using the +- * memory-mapped interface") of ARM IHI 0064D +- */ +- dsb(sy); +- isb(); +- ++ rc = etm4_enable_trace_unit(drvdata); + done: + etm4_cs_lock(drvdata, csa); + +@@ -889,25 +901,12 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + return ret; + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; +- struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct device *etm_dev = &csdev->dev; + struct csdev_access *csa = &csdev->access; +- int i; +- +- etm4_cs_unlock(drvdata, csa); +- etm4_disable_arch_specific(drvdata); +- +- if (!drvdata->skip_power_up) { +- /* power can be removed from the trace unit now */ +- control = etm4x_relaxed_read32(csa, TRCPDCR); +- control &= ~TRCPDCR_PU; +- etm4x_relaxed_write32(csa, control, TRCPDCR); +- } + + control = etm4x_relaxed_read32(csa, TRCPRGCTLR); + +@@ -948,6 +947,28 @@ static void etm4_disable_hw(void *info) + * of ARM IHI 0064H.b. + */ + isb(); ++} ++ ++static void etm4_disable_hw(void *info) ++{ ++ u32 control; ++ struct etmv4_drvdata *drvdata = info; ++ struct etmv4_config *config = &drvdata->config; ++ struct coresight_device *csdev = drvdata->csdev; ++ struct csdev_access *csa = &csdev->access; ++ int i; ++ ++ etm4_cs_unlock(drvdata, csa); ++ etm4_disable_arch_specific(drvdata); ++ ++ if (!drvdata->skip_power_up) { ++ /* power can be removed from the trace unit now */ ++ control = etm4x_relaxed_read32(csa, TRCPDCR); ++ control &= ~TRCPDCR_PU; ++ etm4x_relaxed_write32(csa, control, TRCPDCR); ++ } ++ ++ etm4_disable_trace_unit(drvdata); + + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { +-- +2.51.0 + diff --git a/queue-6.12/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch b/queue-6.12/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch new file mode 100644 index 0000000000..d54a19b9a6 --- /dev/null +++ b/queue-6.12/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch @@ -0,0 +1,44 @@ +From b9fbb0497ec3a9f152090ec8b30e5bc247359cc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 13:11:45 +0530 +Subject: cpufreq/amd-pstate: Call cppc_set_auto_sel() only for online CPUs + +From: Gautham R. Shenoy + +[ Upstream commit bb31fef0d03ed17d587b40e3458786be408fb9df ] + +amd_pstate_change_mode_without_dvr_change() calls cppc_set_auto_sel() +for all the present CPUs. + +However, this callpath eventually calls cppc_set_reg_val() which +accesses the per-cpu cpc_desc_ptr object. This object is initialized +only for online CPUs via acpi_soft_cpu_online() --> +__acpi_processor_start() --> acpi_cppc_processor_probe(). + +Hence, restrict calling cppc_set_auto_sel() to only the online CPUs. + +Fixes: 3ca7bc818d8c ("cpufreq: amd-pstate: Add guided mode control support via sysfs") +Suggested-by: Mario Limonciello (AMD) (kernel.org) +Signed-off-by: Gautham R. Shenoy +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd-pstate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index 62dbc5701e993..c0e073b0425ec 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -1221,7 +1221,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode) + if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE) + return 0; + +- for_each_present_cpu(cpu) { ++ for_each_online_cpu(cpu) { + cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1); + } + +-- +2.51.0 + diff --git a/queue-6.12/cpuset-treat-cpusets-in-attaching-as-populated.patch b/queue-6.12/cpuset-treat-cpusets-in-attaching-as-populated.patch new file mode 100644 index 0000000000..1e4b5eb233 --- /dev/null +++ b/queue-6.12/cpuset-treat-cpusets-in-attaching-as-populated.patch @@ -0,0 +1,115 @@ +From 74d83ede4a68d27c8498b198f744babd91342795 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 02:08:47 +0000 +Subject: cpuset: Treat cpusets in attaching as populated + +From: Chen Ridong + +[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ] + +Currently, the check for whether a partition is populated does not +account for tasks in the cpuset of attaching. This is a corner case +that can leave a task stuck in a partition with no effective CPUs. + +The race condition occurs as follows: + +cpu0 cpu1 + //cpuset A with cpu N +migrate task p to A +cpuset_can_attach +// with effective cpus +// check ok + +// cpuset_mutex is not held // clear cpuset.cpus.exclusive + // making effective cpus empty + update_exclusive_cpumask + // tasks_nocpu_error check ok + // empty effective cpus, partition valid +cpuset_attach +... +// task p stays in A, with non-effective cpus. + +To fix this issue, this patch introduces cs_is_populated, which considers +tasks in the attaching cpuset. This new helper is used in validate_change +and partition_is_populated. + +Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") +Signed-off-by: Chen Ridong +Reviewed-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 13eb986172499..4bb7ad4479e43 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -314,6 +314,15 @@ static inline bool is_in_v2_mode(void) + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); + } + ++static inline bool cpuset_is_populated(struct cpuset *cs) ++{ ++ lockdep_assert_held(&cpuset_mutex); ++ ++ /* Cpusets in the process of attaching should be considered as populated */ ++ return cgroup_is_populated(cs->css.cgroup) || ++ cs->attach_in_progress; ++} ++ + /** + * partition_is_populated - check if partition has tasks + * @cs: partition root to be checked +@@ -326,21 +335,31 @@ static inline bool is_in_v2_mode(void) + static inline bool partition_is_populated(struct cpuset *cs, + struct cpuset *excluded_child) + { +- struct cgroup_subsys_state *css; +- struct cpuset *child; ++ struct cpuset *cp; ++ struct cgroup_subsys_state *pos_css; + +- if (cs->css.cgroup->nr_populated_csets) ++ /* ++ * We cannot call cs_is_populated(cs) directly, as ++ * nr_populated_domain_children may include populated ++ * csets from descendants that are partitions. ++ */ ++ if (cs->css.cgroup->nr_populated_csets || ++ cs->attach_in_progress) + return true; + if (!excluded_child && !cs->nr_subparts) + return cgroup_is_populated(cs->css.cgroup); + + rcu_read_lock(); +- cpuset_for_each_child(child, css, cs) { +- if (child == excluded_child) ++ cpuset_for_each_descendant_pre(cp, pos_css, cs) { ++ if (cp == cs || cp == excluded_child) + continue; +- if (is_partition_valid(child)) ++ ++ if (is_partition_valid(cp)) { ++ pos_css = css_rightmost_descendant(pos_css); + continue; +- if (cgroup_is_populated(child->css.cgroup)) { ++ } ++ ++ if (cpuset_is_populated(cp)) { + rcu_read_unlock(); + return true; + } +@@ -571,7 +590,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) + * be changed to have empty cpus_allowed or mems_allowed. + */ + ret = -ENOSPC; +- if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { ++ if (cpuset_is_populated(cur)) { + if (!cpumask_empty(cur->cpus_allowed) && + cpumask_empty(trial->cpus_allowed)) + goto out; +-- +2.51.0 + diff --git a/queue-6.12/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-6.12/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..3e123a3501 --- /dev/null +++ b/queue-6.12/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From 52af7547d9f032f56f7dec2995a01af701227cc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 43af5fa510c09..7859b0692b42b 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -151,12 +152,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-6.12/crypto-authenc-correctly-pass-einprogress-back-up-to.patch b/queue-6.12/crypto-authenc-correctly-pass-einprogress-back-up-to.patch new file mode 100644 index 0000000000..e0966f963b --- /dev/null +++ b/queue-6.12/crypto-authenc-correctly-pass-einprogress-back-up-to.patch @@ -0,0 +1,202 @@ +From 6e7442bc846e1b0b07362a2af89959031e97b0f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 18:20:17 +0800 +Subject: crypto: authenc - Correctly pass EINPROGRESS back up to the caller + +From: Herbert Xu + +[ Upstream commit 96feb73def02d175850daa0e7c2c90c876681b5c ] + +When authenc is invoked with MAY_BACKLOG, it needs to pass EINPROGRESS +notifications back up to the caller when the underlying algorithm +returns EBUSY synchronously. + +However, if the EBUSY comes from the second part of an authenc call, +i.e., it is asynchronous, both the EBUSY and the subsequent EINPROGRESS +notification must not be passed to the caller. + +Implement this by passing a mask to the function that starts the +second half of authenc and using it to determine whether EBUSY +and EINPROGRESS should be passed to the caller. + +This was a deficiency in the original implementation of authenc +because it was not expected to be used with MAY_BACKLOG. + +Reported-by: Ingo Franzki +Reported-by: Mikulas Patocka +Fixes: 180ce7e81030 ("crypto: authenc - Add EINPROGRESS check") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/authenc.c | 75 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/crypto/authenc.c b/crypto/authenc.c +index 3aaf3ab4e360f..d04068af9833e 100644 +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -39,7 +39,7 @@ struct authenc_request_ctx { + + static void authenc_request_complete(struct aead_request *req, int err) + { +- if (err != -EINPROGRESS) ++ if (err != -EINPROGRESS && err != -EBUSY) + aead_request_complete(req, err); + } + +@@ -109,27 +109,42 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, + return err; + } + +-static void authenc_geniv_ahash_done(void *data, int err) ++static void authenc_geniv_ahash_finish(struct aead_request *req) + { +- struct aead_request *req = data; + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); + struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + +- if (err) +- goto out; +- + scatterwalk_map_and_copy(ahreq->result, req->dst, + req->assoclen + req->cryptlen, + crypto_aead_authsize(authenc), 1); ++} + +-out: ++static void authenc_geniv_ahash_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); + aead_request_complete(req, err); + } + +-static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ++/* ++ * Used when the ahash request was invoked in the async callback context ++ * of the previous skcipher request. Eat any EINPROGRESS notifications. ++ */ ++static void authenc_geniv_ahash_done2(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); ++ authenc_request_complete(req, err); ++} ++ ++static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -138,6 +153,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + struct crypto_ahash *auth = ctx->auth; + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *hash = areq_ctx->tail; + int err; + +@@ -145,7 +161,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + ahash_request_set_crypt(ahreq, req->dst, hash, + req->assoclen + req->cryptlen); + ahash_request_set_callback(ahreq, flags, +- authenc_geniv_ahash_done, req); ++ mask ? authenc_geniv_ahash_done2 : ++ authenc_geniv_ahash_done, req); + + err = crypto_ahash_digest(ahreq); + if (err) +@@ -161,12 +178,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) + { + struct aead_request *areq = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_genicv(areq, 0); +- +-out: ++ if (err) { ++ aead_request_complete(areq, err); ++ return; ++ } ++ err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(areq, err); + } + +@@ -219,11 +235,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_genicv(req, aead_request_flags(req)); ++ return crypto_authenc_genicv(req, 0); ++} ++ ++static void authenc_decrypt_tail_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ authenc_request_complete(req, err); + } + + static int crypto_authenc_decrypt_tail(struct aead_request *req, +- unsigned int flags) ++ unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -234,6 +257,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + struct skcipher_request *skreq = (void *)(areq_ctx->tail + + ictx->reqoff); + unsigned int authsize = crypto_aead_authsize(authenc); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *ihash = ahreq->result + authsize; + struct scatterlist *src, *dst; + +@@ -250,7 +274,9 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + + skcipher_request_set_tfm(skreq, ctx->enc); + skcipher_request_set_callback(skreq, flags, +- req->base.complete, req->base.data); ++ mask ? authenc_decrypt_tail_done : ++ req->base.complete, ++ mask ? req : req->base.data); + skcipher_request_set_crypt(skreq, src, dst, + req->cryptlen - authsize, req->iv); + +@@ -261,12 +287,11 @@ static void authenc_verify_ahash_done(void *data, int err) + { + struct aead_request *req = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_decrypt_tail(req, 0); +- +-out: ++ if (err) { ++ aead_request_complete(req, err); ++ return; ++ } ++ err = crypto_authenc_decrypt_tail(req, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(req, err); + } + +@@ -293,7 +318,7 @@ static int crypto_authenc_decrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); ++ return crypto_authenc_decrypt_tail(req, 0); + } + + static int crypto_authenc_init_tfm(struct crypto_aead *tfm) +-- +2.51.0 + diff --git a/queue-6.12/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-6.12/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..66c0ac66ca --- /dev/null +++ b/queue-6.12/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From edc242180ee7d95a4c39853a5a993df6ed65b2d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index bcca55bff910e..286e0d4b8f95e 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-6.12/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-6.12/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..0fe377f3b7 --- /dev/null +++ b/queue-6.12/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From 191b3e4c69afb3480ebe5ac13b692e4fac78db86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 711c299713687..d0b154d13f445 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3493,6 +3493,7 @@ static void qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -3500,6 +3501,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -3513,11 +3515,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-6.12/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch b/queue-6.12/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch new file mode 100644 index 0000000000..4fef229b68 --- /dev/null +++ b/queue-6.12/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch @@ -0,0 +1,40 @@ +From 28dd053c2c75eecb1c24b1e7e3b8a8ae65c639b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:56:48 +0000 +Subject: crypto: iaa - Fix incorrect return value in save_iaa_wq() + +From: Zilin Guan + +[ Upstream commit 76ce17f6f7f78ab79b9741388bdb4dafa985b4e9 ] + +The save_iaa_wq() function unconditionally returns 0, even when an error +is encountered. This prevents the error code from being propagated to the +caller. + +Fix this by returning the 'ret' variable, which holds the actual status +of the operations within the function. + +Fixes: ea7a5cbb43696 ("crypto: iaa - Add Intel IAA Compression Accelerator crypto driver core") +Signed-off-by: Zilin Guan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/iaa/iaa_crypto_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c +index df2728cccf8b3..e9391cf2c397c 100644 +--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c ++++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c +@@ -807,7 +807,7 @@ static int save_iaa_wq(struct idxd_wq *wq) + if (!cpus_per_iaa) + cpus_per_iaa = 1; + out: +- return 0; ++ return ret; + } + + static void remove_iaa_wq(struct idxd_wq *wq) +-- +2.51.0 + diff --git a/queue-6.12/crypto-starfive-correctly-handle-return-of-sg_nents_.patch b/queue-6.12/crypto-starfive-correctly-handle-return-of-sg_nents_.patch new file mode 100644 index 0000000000..5615f3bf2f --- /dev/null +++ b/queue-6.12/crypto-starfive-correctly-handle-return-of-sg_nents_.patch @@ -0,0 +1,51 @@ +From e27840b77d7a5452a18241e5c0aab6cc7c0b7dd5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:54:38 +0800 +Subject: crypto: starfive - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit e9eb52037a529fbb307c290e9951a62dd728b03d ] + +The return value of sg_nents_for_len was assigned to an unsigned long +in starfive_hash_digest, causing negative error codes to be converted +to large positive integers. + +Add error checking for sg_nents_for_len and return immediately on +failure to prevent potential buffer overflows. + +Fixes: 7883d1b28a2b ("crypto: starfive - Add hash and HMAC support") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-hash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c +index 2c60a1047bc39..c0b09ca1cc2ed 100644 +--- a/drivers/crypto/starfive/jh7110-hash.c ++++ b/drivers/crypto/starfive/jh7110-hash.c +@@ -326,6 +326,7 @@ static int starfive_hash_digest(struct ahash_request *req) + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_dev *cryp = ctx->cryp; ++ int sg_len; + + memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); + +@@ -334,7 +335,10 @@ static int starfive_hash_digest(struct ahash_request *req) + rctx->in_sg = req->src; + rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + rctx->digsize = crypto_ahash_digestsize(tfm); +- rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ if (sg_len < 0) ++ return sg_len; ++ rctx->in_sg_len = sg_len; + ctx->rctx = rctx; + + return crypto_transfer_hash_request_to_engine(cryp->engine, req); +-- +2.51.0 + diff --git a/queue-6.12/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-6.12/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..95f98c460a --- /dev/null +++ b/queue-6.12/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 91e9e1352d54c08e585c0d2e2b46134a859c6a12 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index c9a6de110b742..af31fddb47db1 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-6.12/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch b/queue-6.12/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch new file mode 100644 index 0000000000..673eb3c87e --- /dev/null +++ b/queue-6.12/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch @@ -0,0 +1,91 @@ +From 54d2e389706accf4097e28acef91bb8360bde993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Oct 2024 15:19:42 +0530 +Subject: drm: atmel-hlcdc: fix atmel_xlcdc_plane_setup_scaler() + +From: Cyrille Pitchen + +[ Upstream commit a312acdcec57b3955fbf1f3057c13a6d38e4aa2a ] + +On SoCs, like the SAM9X75, which embed the XLCDC ip, the registers that +configure the unified scaling engine were not filled with proper values. + +Indeed, for YCbCr formats, the VXSCFACT bitfield of the HEOCFG25 +register and the HXSCFACT bitfield of the HEOCFG27 register were +incorrect. + +For 4:2:0 formats, both vertical and horizontal factors for +chroma chanels should be divided by 2 from the factors for the luma +channel. Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VSXCFACT = VFACTOR / 2 +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +However, for 4:2:2 formats, only the horizontal factor for chroma +chanels should be divided by 2 from the factor for the luma channel; +the vertical factor is the same for all the luma and chroma channels. +Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VXSCFACT = VFACTOR +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +Fixes: d498771b0b83 ("drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops") +Signed-off-by: Cyrille Pitchen +Reviewed-by: Dmitry Baryshkov +Acked-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20241014094942.325211-1-manikandan.m@microchip.com +Signed-off-by: Manikandan Muralidharan +Signed-off-by: Sasha Levin +--- + .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 27 ++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +index 4a7ba0918eca1..3787db014501e 100644 +--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c ++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +@@ -365,13 +365,34 @@ void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, + xfactor); + + /* +- * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration +- * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half ++ * With YCbCr 4:2:0 window resampling, configuration register ++ * LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT values are half + * the value of yfactor and xfactor. ++ * ++ * On the other hand, with YCbCr 4:2:2 window resampling, only the ++ * configuration register LCDC_HEOCFG27.HXSCFACT value is half the value ++ * of the xfactor; the value of LCDC_HEOCFG25.VXSCFACT is yfactor (no ++ * division by 2). + */ +- if (state->base.fb->format->format == DRM_FORMAT_YUV420) { ++ switch (state->base.fb->format->format) { ++ /* YCbCr 4:2:2 */ ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_UYVY: ++ case DRM_FORMAT_YVYU: ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_YUV422: ++ case DRM_FORMAT_NV61: ++ xfactor /= 2; ++ break; ++ ++ /* YCbCr 4:2:0 */ ++ case DRM_FORMAT_YUV420: ++ case DRM_FORMAT_NV21: + yfactor /= 2; + xfactor /= 2; ++ break; ++ default: ++ break; + } + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2, +-- +2.51.0 + diff --git a/queue-6.12/drm-imagination-fix-reference-to-devm_platform_get_a.patch b/queue-6.12/drm-imagination-fix-reference-to-devm_platform_get_a.patch new file mode 100644 index 0000000000..9559c0dd8d --- /dev/null +++ b/queue-6.12/drm-imagination-fix-reference-to-devm_platform_get_a.patch @@ -0,0 +1,40 @@ +From 64f51205470d5ee662fffb8164c8ef39c3a9176d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 16:00:28 +0100 +Subject: drm/imagination: Fix reference to + devm_platform_get_and_ioremap_resource() + +From: Geert Uytterhoeven + +[ Upstream commit f1aa93005d0d6fb3293ca9c3eb08d1d1557117bf ] + +The call to devm_platform_ioremap_resource() was replaced by a call to +devm_platform_get_and_ioremap_resource(), but the comment referring to +the function's possible returned error codes was not updated. + +Fixes: 927f3e0253c11276 ("drm/imagination: Implement MIPS firmware processor and MMU support") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Matt Coster +Link: https://patch.msgid.link/2266514318480d17f52c7e5e67578dae6827914e.1761745586.git.geert+renesas@glider.be +Signed-off-by: Matt Coster +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/imagination/pvr_device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c +index 1704c0268589b..6bccbde4945ba 100644 +--- a/drivers/gpu/drm/imagination/pvr_device.c ++++ b/drivers/gpu/drm/imagination/pvr_device.c +@@ -46,7 +46,7 @@ + * + * Return: + * * 0 on success, or +- * * Any error returned by devm_platform_ioremap_resource(). ++ * * Any error returned by devm_platform_get_and_ioremap_resource(). + */ + static int + pvr_device_reg_init(struct pvr_device *pvr_dev) +-- +2.51.0 + diff --git a/queue-6.12/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-6.12/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..73b68eb2c7 --- /dev/null +++ b/queue-6.12/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From 4e5c2fce940b71dad27dbb4ac2f170f77c823185 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 9b75727e0861c..cb6d829d93db1 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-6.12/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch b/queue-6.12/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch new file mode 100644 index 0000000000..9a0efba9c2 --- /dev/null +++ b/queue-6.12/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch @@ -0,0 +1,42 @@ +From edf0ff325c8d0a8ada6d57ad96c99c0d65d42fb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:40:50 +0200 +Subject: drm/msm/a2xx: stop over-complaining about the legacy firmware + +From: Dmitry Baryshkov + +[ Upstream commit a3a22373fce576560757f5616eb48dbf85891d9c ] + +If the rootfs have a legacy A200 firmware, currently the driver will +complain each time the hw is reinited (which can happen a lot). E.g. +with GL testsuite the hw is reinited after each test, spamming the +console. + +Make sure that the message is printed only once: when we detect the +firmware that doesn't support protection. + +Fixes: 302295070d3c ("drm/msm/a2xx: support loading legacy (iMX) firmware") +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/688098/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +index 0dc255ddf5ceb..2e25af3462ab6 100644 +--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +@@ -234,7 +234,7 @@ static int a2xx_hw_init(struct msm_gpu *gpu) + * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225). + * Older firmware files, which lack protection support, have 0 instead. + */ +- if (ptr[1] == 0) { ++ if (ptr[1] == 0 && !a2xx_gpu->protection_disabled) { + dev_warn(gpu->dev->dev, + "Legacy firmware detected, disabling protection support\n"); + a2xx_gpu->protection_disabled = true; +-- +2.51.0 + diff --git a/queue-6.12/drm-msm-a6xx-fix-the-gemnoc-workaround.patch b/queue-6.12/drm-msm-a6xx-fix-the-gemnoc-workaround.patch new file mode 100644 index 0000000000..02b81296f9 --- /dev/null +++ b/queue-6.12/drm-msm-a6xx-fix-the-gemnoc-workaround.patch @@ -0,0 +1,55 @@ +From 992e672a39a5fb8fe9a65e6433cc8dafe0fa57d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:30 +0530 +Subject: drm/msm/a6xx: Fix the gemnoc workaround + +From: Akhil P Oommen + +[ Upstream commit ff7a6de043fce21ea5891311746b16121b385c59 ] + +Correct the register offset and enable this workaround for all A7x +and newer GPUs to match the recommendation. Also, downstream does this +w/a after moving the fence to allow mode. So do the same. + +Fixes: dbfbb376b50c ("drm/msm/a6xx: Add A621 support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688997/ +Message-ID: <20251118-kaana-gpu-support-v4-3-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index bfb1225a47c50..e2ea50862a413 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -435,8 +435,9 @@ static void a6xx_gemnoc_workaround(struct a6xx_gmu *gmu) + * in the power down sequence not being fully executed. That in turn can + * prevent CX_GDSC from collapsing. Assert Qactive to avoid this. + */ +- if (adreno_is_a621(adreno_gpu) || adreno_is_7c3(adreno_gpu)) +- gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, BIT(0)); ++ if (adreno_is_a7xx(adreno_gpu) || (adreno_is_a621(adreno_gpu) || ++ adreno_is_7c3(adreno_gpu))) ++ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, BIT(0)); + } + + /* Let the GMU know that we are about to go into slumber */ +@@ -472,10 +473,9 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) + } + + out: +- a6xx_gemnoc_workaround(gmu); +- + /* Put fence into allow mode */ + gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); ++ a6xx_gemnoc_workaround(gmu); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch b/queue-6.12/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch new file mode 100644 index 0000000000..f7762f1361 --- /dev/null +++ b/queue-6.12/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch @@ -0,0 +1,56 @@ +From 7dd98cd4f722fb6e81af4ed77643e292efa7c9c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:29 +0530 +Subject: drm/msm/a6xx: Flush LRZ cache before PT switch + +From: Akhil P Oommen + +[ Upstream commit 180349b8407f3b268b2ceac0e590b8199e043081 ] + +As per the recommendation, A7x and newer GPUs should flush the LRZ cache +before switching the pagetable. Update a6xx_set_pagetable() to do this. +While we are at it, sync both BV and BR before issuing a +CP_RESET_CONTEXT_STATE command, to match the downstream sequence. + +Fixes: af66706accdf ("drm/msm/a6xx: Add skeleton A7xx support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688995/ +Message-ID: <20251118-kaana-gpu-support-v4-2-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index 29d39b2bd86e0..2407140508d8a 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -125,7 +125,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + OUT_RING(ring, submit->seqno - 1); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BOTH); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); + + /* Reset state used to synchronize BR and BV */ + OUT_PKT7(ring, CP_RESET_CONTEXT_STATE, 1); +@@ -136,7 +136,13 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + CP_RESET_CONTEXT_STATE_0_RESET_GLOBAL_LOCAL_TS); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BR); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); ++ ++ OUT_PKT7(ring, CP_EVENT_WRITE, 1); ++ OUT_RING(ring, LRZ_FLUSH); ++ ++ OUT_PKT7(ring, CP_THREAD_CONTROL, 1); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); + } + + if (!sysprof) { +-- +2.51.0 + diff --git a/queue-6.12/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch b/queue-6.12/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch new file mode 100644 index 0000000000..1ca1c8b2d8 --- /dev/null +++ b/queue-6.12/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch @@ -0,0 +1,92 @@ +From 38b23d0f59717f340b797b2f1458c5abf0fd6e25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:39 +0530 +Subject: drm/msm/a6xx: Improve MX rail fallback in RPMH vote init + +From: Akhil P Oommen + +[ Upstream commit ca04ce7a2f22652fdf6489fa7e02e7d2c08698f4 ] + +Current logic assumes that the voltage corners in both MxG and MxA are +always same. This is not true for recent targets. So, rework the rpmh init +sequence to probe and calculate the votes with the respective rails, ie, +GX rails should use MxG as secondary rail and Cx rail should use MxA as +the secondary rail. + +Fixes: d6225e0cd096 ("drm/msm/adreno: Add support for X185 GPU") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/689014/ +Message-ID: <20251118-kaana-gpu-support-v4-12-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index e2ea50862a413..3e36cec3801ed 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -1324,13 +1324,14 @@ static unsigned int a6xx_gmu_get_arc_level(struct device *dev, + } + + static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, +- unsigned long *freqs, int freqs_count, const char *id) ++ unsigned long *freqs, int freqs_count, ++ const char *pri_id, const char *sec_id) + { + int i, j; + const u16 *pri, *sec; + size_t pri_count, sec_count; + +- pri = cmd_db_read_aux_data(id, &pri_count); ++ pri = cmd_db_read_aux_data(pri_id, &pri_count); + if (IS_ERR(pri)) + return PTR_ERR(pri); + /* +@@ -1341,13 +1342,7 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, + if (!pri_count) + return -EINVAL; + +- /* +- * Some targets have a separate gfx mxc rail. So try to read that first and then fall back +- * to regular mx rail if it is missing +- */ +- sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); +- if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER)) +- sec = cmd_db_read_aux_data("mx.lvl", &sec_count); ++ sec = cmd_db_read_aux_data(sec_id, &sec_count); + if (IS_ERR(sec)) + return PTR_ERR(sec); + +@@ -1412,15 +1407,24 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu) + struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu); + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + struct msm_gpu *gpu = &adreno_gpu->base; ++ const char *sec_id; ++ const u16 *gmxc; + int ret; + ++ gmxc = cmd_db_read_aux_data("gmxc.lvl", NULL); ++ if (gmxc == ERR_PTR(-EPROBE_DEFER)) ++ return -EPROBE_DEFER; ++ ++ /* If GMxC is present, prefer that as secondary rail for GX votes */ ++ sec_id = IS_ERR_OR_NULL(gmxc) ? "mx.lvl" : "gmxc.lvl"; ++ + /* Build the GX votes */ + ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes, +- gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl"); ++ gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl", sec_id); + + /* Build the CX votes */ + ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes, +- gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl"); ++ gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl", "mx.lvl"); + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.12/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch b/queue-6.12/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch new file mode 100644 index 0000000000..ca746d42da --- /dev/null +++ b/queue-6.12/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch @@ -0,0 +1,45 @@ +From 174ed9c0955adca2c963e64e661dd273f75995d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:35:17 +0200 +Subject: drm/msm/dpu: drop dpu_hw_dsc_destroy() prototype + +From: Dmitry Baryshkov + +[ Upstream commit d9792823d18ff9895eaf5769a29a54804f24bc25 ] + +The commit a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for +HW blocks") dropped all dpu_hw_foo_destroy() functions, but the +prototype for dpu_hw_dsc_destroy() was omitted. Drop it now to clean up +the header. + +Fixes: a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for HW blocks") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Reviewed-by: Jessica Zhang +Patchwork: https://patchwork.freedesktop.org/patch/683697/ +Link: https://lore.kernel.org/r/20251027-dpu-drop-dsc-destroy-v1-1-968128de4bf6@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +index 989c88d2449b6..2214b25afac45 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +@@ -84,12 +84,6 @@ struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, + const struct dpu_dsc_cfg *cfg, + void __iomem *addr); + +-/** +- * dpu_hw_dsc_destroy - destroys dsc driver context +- * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init +- */ +-void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc); +- + static inline struct dpu_hw_dsc *to_dpu_hw_dsc(struct dpu_hw_blk *hw) + { + return container_of(hw, struct dpu_hw_dsc, base); +-- +2.51.0 + diff --git a/queue-6.12/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch b/queue-6.12/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch new file mode 100644 index 0000000000..c3a3d9d46d --- /dev/null +++ b/queue-6.12/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch @@ -0,0 +1,55 @@ +From 25dff992925fc5b0506c4e023005a79374accd13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 17:03:22 -0600 +Subject: drm/nouveau: restrict the flush page to a 32-bit address + +From: Timur Tabi + +[ Upstream commit 04d98b3452331fa53ec3b698b66273af6ef73288 ] + +The flush page DMA address is stored in a special register that is not +associated with the GPU's standard DMA range. For example, on Turing, +the GPU's MMU can handle 47-bit addresses, but the flush page address +register is limited to 40 bits. + +At the point during device initialization when the flush page is +allocated, the DMA mask is still at its default of 32 bits. So even +though it's unlikely that the flush page could exist above a 40-bit +address, the dma_map_page() call could fail, e.g. if IOMMU is disabled +and the address is above 32 bits. The simplest way to achieve all +constraints is to allocate the page in the DMA32 zone. Since the flush +page is literally just a page, this is an acceptable limitation. The +alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper +and later) bits, but that could have unforseen side effects. + +In situations where the flush page is allocated above 32 bits and IOMMU +is disabled, you will get an error like this: + +nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0). + +Fixes: 5728d064190e ("drm/nouveau/fb: handle sysmem flush page from common code") +Signed-off-by: Timur Tabi +Reviewed-by: Lyude Paul +Signed-off-by: Lyude Paul +Link: https://patch.msgid.link/20251113230323.1271726-1-ttabi@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +index 8a286a9349ac6..7ce1b65e2c1c2 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +@@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, + mutex_init(&fb->tags.mutex); + + if (func->sysmem.flush_page_init) { +- fb->sysmem.flush_page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + if (!fb->sysmem.flush_page) + return -ENOMEM; + +-- +2.51.0 + diff --git a/queue-6.12/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-6.12/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..971c650ac7 --- /dev/null +++ b/queue-6.12/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From 27c232f5586f77ca6e3f600bfdbb01f9dbefa9d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 272490b9565bb..f06dca12febe4 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -62,7 +62,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + int ret; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch b/queue-6.12/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch new file mode 100644 index 0000000000..647688ae15 --- /dev/null +++ b/queue-6.12/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch @@ -0,0 +1,64 @@ +From fadf3821ad4afc3caa7558443a4e1464dd5b995c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 17:21:18 +0000 +Subject: drm/panthor: Avoid adding of kernel BOs to extobj list + +From: Akash Goel + +[ Upstream commit ce04ec03a9c2c4f3e60e26f21311b25d5a478208 ] + +The kernel BOs unnecessarily got added to the external objects list +of drm_gpuvm, when mapping to GPU, which would have resulted in few +extra CPU cycles being spent at the time of job submission as +drm_exec_until_all_locked() loop iterates over all external objects. + +Kernel BOs are private to a VM and so they share the dma_resv object of +the dummy GEM object created for a VM. Use of DRM_EXEC_IGNORE_DUPLICATES +flag ensured the recursive locking of the dummy GEM object was ignored. +Also no extra space got allocated to add fences to the dma_resv object +of dummy GEM object. So no other impact apart from few extra CPU cycles. + +This commit sets the pointer to dma_resv object of GEM object of +kernel BOs before they are mapped to GPU, to prevent them from +being added to external objects list. + +v2: Add R-bs and fixes tags + +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251120172118.2741724-1-akash.goel@arm.com +Signed-off-by: Boris Brezillon +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index 8387a075150bd..0438b80a6434b 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -88,6 +88,9 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + bo = to_panthor_bo(&obj->base); + kbo->obj = &obj->base; + bo->flags = bo_flags; ++ bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); ++ drm_gem_object_get(bo->exclusive_vm_root_gem); ++ bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + + /* The system and GPU MMU page size might differ, which becomes a + * problem for FW sections that need to be mapped at explicit address +@@ -105,9 +108,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + goto err_free_va; + + kbo->vm = panthor_vm_get(vm); +- bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); +- drm_gem_object_get(bo->exclusive_vm_root_gem); +- bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + return kbo; + + err_free_va: +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-group_free_queue-for-partially-initi.patch b/queue-6.12/drm-panthor-fix-group_free_queue-for-partially-initi.patch new file mode 100644 index 0000000000..7a507572d1 --- /dev/null +++ b/queue-6.12/drm-panthor-fix-group_free_queue-for-partially-initi.patch @@ -0,0 +1,45 @@ +From 77854ca7e29639ed80430340c4346954d18fc147 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:18 +0100 +Subject: drm/panthor: Fix group_free_queue() for partially initialized queues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Boris Brezillon + +[ Upstream commit 94a6d20feadbbe24e8a7b1c56394789ea5358fcc ] + +group_free_queue() can be called on a partially initialized queue +object if something fails in group_create_queue(). Make sure we don't +call drm_sched_entity_destroy() on an entity that hasn't been +initialized. + +Fixes: 7d9c3442b02a ("drm/panthor: Defer scheduler entitiy destruction to queue release") +Reviewed-by: Adrián Larumbe +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 875b9a78d34bc..81ea3a79ab49c 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -865,7 +865,8 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue * + if (IS_ERR_OR_NULL(queue)) + return; + +- drm_sched_entity_destroy(&queue->entity); ++ if (queue->entity.fence_context) ++ drm_sched_entity_destroy(&queue->entity); + + if (queue->scheduler.ops) + drm_sched_fini(&queue->scheduler); +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-potential-memleak-of-vma-structure.patch b/queue-6.12/drm-panthor-fix-potential-memleak-of-vma-structure.patch new file mode 100644 index 0000000000..cf6149eb7c --- /dev/null +++ b/queue-6.12/drm-panthor-fix-potential-memleak-of-vma-structure.patch @@ -0,0 +1,69 @@ +From 53a142c568a72148af91b97e3ae439dddae317ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 09:10:42 +0100 +Subject: drm/panthor: Fix potential memleak of vma structure + +From: Akash Goel + +[ Upstream commit 4492d54d59872bb72e119ff9f77969ab4d8a0e6b ] + +This commit addresses a memleak issue of panthor_vma (or drm_gpuva) +structure in Panthor driver, that can happen if the GPU page table +update operation to map the pages fail. +The issue is very unlikely to occur in practice. + +v2: Add panthor_vm_op_ctx_return_vma() helper (Boris) + +v3: Add WARN_ON_ONCE (Boris) + +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patch.msgid.link/20251021081042.1377406-1-akash.goel@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c +index d548a6e0311dd..ed769749ec354 100644 +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1139,6 +1139,20 @@ static void panthor_vm_cleanup_op_ctx(struct panthor_vm_op_ctx *op_ctx, + } + } + ++static void ++panthor_vm_op_ctx_return_vma(struct panthor_vm_op_ctx *op_ctx, ++ struct panthor_vma *vma) ++{ ++ for (u32 i = 0; i < ARRAY_SIZE(op_ctx->preallocated_vmas); i++) { ++ if (!op_ctx->preallocated_vmas[i]) { ++ op_ctx->preallocated_vmas[i] = vma; ++ return; ++ } ++ } ++ ++ WARN_ON_ONCE(1); ++} ++ + static struct panthor_vma * + panthor_vm_op_ctx_get_vma(struct panthor_vm_op_ctx *op_ctx) + { +@@ -2037,8 +2051,10 @@ static int panthor_gpuva_sm_step_map(struct drm_gpuva_op *op, void *priv) + ret = panthor_vm_map_pages(vm, op->map.va.addr, flags_to_prot(vma->flags), + op_ctx->map.sgt, op->map.gem.offset, + op->map.va.range); +- if (ret) ++ if (ret) { ++ panthor_vm_op_ctx_return_vma(op_ctx, vma); + return ret; ++ } + + /* Ref owned by the mapping now, clear the obj field so we don't release the + * pinning/obj ref behind GPUVA's back. +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-race-with-suspend-during-unplug.patch b/queue-6.12/drm-panthor-fix-race-with-suspend-during-unplug.patch new file mode 100644 index 0000000000..7244f35d53 --- /dev/null +++ b/queue-6.12/drm-panthor-fix-race-with-suspend-during-unplug.patch @@ -0,0 +1,58 @@ +From 6a1f87476e44aea8b3f4d68fbc443602fa9c57d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 12:32:41 +0200 +Subject: drm/panthor: Fix race with suspend during unplug + +From: Ketil Johnsen + +[ Upstream commit 08be57e6e8aa20ea5a6dd2552e38ac168d6a9b11 ] + +There is a race between panthor_device_unplug() and +panthor_device_suspend() which can lead to IRQ handlers running on a +powered down GPU. This is how it can happen: +- unplug routine calls drm_dev_unplug() +- panthor_device_suspend() can now execute, and will skip a lot of + important work because the device is currently marked as unplugged. +- IRQs will remain active in this case and IRQ handlers can therefore + try to access a powered down GPU. + +The fix is simply to take the PM ref in panthor_device_unplug() a +little bit earlier, before drm_dev_unplug(). + +Signed-off-by: Ketil Johnsen +Fixes: 5fe909cae118a ("drm/panthor: Add the device logical block") +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251022103242.1083311-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c +index 01dff89bed4e1..e36d414044e02 100644 +--- a/drivers/gpu/drm/panthor/panthor_device.c ++++ b/drivers/gpu/drm/panthor/panthor_device.c +@@ -64,6 +64,8 @@ void panthor_device_unplug(struct panthor_device *ptdev) + return; + } + ++ drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); ++ + /* Call drm_dev_unplug() so any access to HW blocks happening after + * that point get rejected. + */ +@@ -74,8 +76,6 @@ void panthor_device_unplug(struct panthor_device *ptdev) + */ + mutex_unlock(&ptdev->unplug.lock); + +- drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); +- + /* Now, try to cleanly shutdown the GPU before the device resources + * get reclaimed. + */ +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch b/queue-6.12/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch new file mode 100644 index 0000000000..eced3633bd --- /dev/null +++ b/queue-6.12/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch @@ -0,0 +1,68 @@ +From 2b840f59992ab06c21bd805c680e2b2537bb3146 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:48:15 +0100 +Subject: drm/panthor: Fix UAF on kernel BO VA nodes + +From: Boris Brezillon + +[ Upstream commit 98dd5143447af0ee33551776d8b2560c35d0bc4a ] + +If the MMU is down, panthor_vm_unmap_range() might return an error. +We expect the page table to be updated still, and if the MMU is blocked, +the rest of the GPU should be blocked too, so no risk of accessing +physical memory returned to the system (which the current code doesn't +cover for anyway). + +Proceed with the rest of the cleanup instead of bailing out and leaving +the va_node inserted in the drm_mm, which leads to UAF when other +adjacent nodes are removed from the drm_mm tree. + +Reported-by: Lars-Ivar Hesselberg Simonsen +Closes: https://gitlab.freedesktop.org/panfrost/linux/-/issues/57 +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251031154818.821054-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index be97d56bc011d..8387a075150bd 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -32,7 +32,6 @@ static void panthor_gem_free_object(struct drm_gem_object *obj) + void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + { + struct panthor_vm *vm; +- int ret; + + if (IS_ERR_OR_NULL(bo)) + return; +@@ -40,18 +39,11 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + vm = bo->vm; + panthor_kernel_bo_vunmap(bo); + +- if (drm_WARN_ON(bo->obj->dev, +- to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) +- goto out_free_bo; +- +- ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); +- if (ret) +- goto out_free_bo; +- ++ drm_WARN_ON(bo->obj->dev, ++ to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)); ++ panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); + panthor_vm_free_va(vm, &bo->va_node); + drm_gem_object_put(bo->obj); +- +-out_free_bo: + panthor_vm_put(vm); + kfree(bo); + } +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch b/queue-6.12/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch new file mode 100644 index 0000000000..a845370966 --- /dev/null +++ b/queue-6.12/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch @@ -0,0 +1,43 @@ +From a2ec007f3ccaf5a77cbf02f0170c6c38fbafa823 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:02:15 +0100 +Subject: drm/panthor: Fix UAF race between device unplug and FW event + processing + +From: Ketil Johnsen + +[ Upstream commit 7051f6ba968fa69918d72cc26de4d6cf7ea05b90 ] + +The function panthor_fw_unplug() will free the FW memory sections. +The problem is that there could still be pending FW events which are yet +not handled at this point. process_fw_events_work() can in this case try +to access said freed memory. + +Simply call disable_work_sync() to both drain and prevent future +invocation of process_fw_events_work(). + +Signed-off-by: Ketil Johnsen +Fixes: de85488138247 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251027140217.121274-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 81ea3a79ab49c..1d95decddc273 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3696,6 +3696,7 @@ void panthor_sched_unplug(struct panthor_device *ptdev) + struct panthor_scheduler *sched = ptdev->scheduler; + + cancel_delayed_work_sync(&sched->tick_work); ++ disable_work_sync(&sched->fw_events_work); + + mutex_lock(&sched->lock); + if (sched->pm.has_ref) { +-- +2.51.0 + diff --git a/queue-6.12/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch b/queue-6.12/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch new file mode 100644 index 0000000000..c320b22e91 --- /dev/null +++ b/queue-6.12/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch @@ -0,0 +1,39 @@ +From ee782433dc4ac51a533f412f0070bd14b213ee5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:17 +0100 +Subject: drm/panthor: Handle errors returned by drm_sched_entity_init() + +From: Boris Brezillon + +[ Upstream commit bb7939e332c64c4ef33974a0eae4f3841acfa8eb ] + +In practice it's not going to fail because we're passing the current +sanity checks done by drm_sched_entity_init(), and that's the only +reason it would return an error, but better safe than sorry. + +Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-1-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 0bc5b69ec636b..875b9a78d34bc 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3307,6 +3307,8 @@ group_create_queue(struct panthor_group *group, + + drm_sched = &queue->scheduler; + ret = drm_sched_entity_init(&queue->entity, 0, &drm_sched, 1, NULL); ++ if (ret) ++ goto err_free_queue; + + return queue; + +-- +2.51.0 + diff --git a/queue-6.12/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-6.12/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..573d859531 --- /dev/null +++ b/queue-6.12/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From e9d8c541352368fff33079c40065e623bd526648 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index e157541783959..d066345d5930b 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -94,7 +94,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch b/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch new file mode 100644 index 0000000000..0a44664de3 --- /dev/null +++ b/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch @@ -0,0 +1,185 @@ +From 7daee35fc88fa9700ae581a5f0ff17075678604b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:14:38 +0200 +Subject: dt-bindings: clock: qcom,x1e80100-gcc: Add missing USB4 clocks/resets + +From: Konrad Dybcio + +[ Upstream commit e4c4f5a1ae18a7828c2bfaf9dfe2473632b92d1b ] + +Some of the USB4 muxes, RCGs and resets were not initially described. + +Add indices for them to allow extending the driver. + +Acked-by: Rob Herring (Arm) +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251003-topic-hamoa_gcc_usb4-v2-1-61d27a14ee65@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: 8abe970efea5 ("clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets") +Signed-off-by: Sasha Levin +--- + .../bindings/clock/qcom,x1e80100-gcc.yaml | 62 +++++++++++++++++-- + include/dt-bindings/clock/qcom,x1e80100-gcc.h | 61 ++++++++++++++++++ + 2 files changed, 119 insertions(+), 4 deletions(-) + +diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +index 5951a60ab0815..61ff277eae544 100644 +--- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml ++++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +@@ -28,9 +28,36 @@ properties: + - description: PCIe 5 pipe clock + - description: PCIe 6a pipe clock + - description: PCIe 6b pipe clock +- - description: USB QMP Phy 0 clock source +- - description: USB QMP Phy 1 clock source +- - description: USB QMP Phy 2 clock source ++ - description: USB4_0 QMPPHY clock source ++ - description: USB4_1 QMPPHY clock source ++ - description: USB4_2 QMPPHY clock source ++ - description: USB4_0 PHY DP0 GMUX clock source ++ - description: USB4_0 PHY DP1 GMUX clock source ++ - description: USB4_0 PHY PCIE PIPEGMUX clock source ++ - description: USB4_0 PHY PIPEGMUX clock source ++ - description: USB4_0 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_1 PHY DP0 GMUX 2 clock source ++ - description: USB4_1 PHY DP1 GMUX 2 clock source ++ - description: USB4_1 PHY PCIE PIPEGMUX clock source ++ - description: USB4_1 PHY PIPEGMUX clock source ++ - description: USB4_1 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_2 PHY DP0 GMUX 2 clock source ++ - description: USB4_2 PHY DP1 GMUX 2 clock source ++ - description: USB4_2 PHY PCIE PIPEGMUX clock source ++ - description: USB4_2 PHY PIPEGMUX clock source ++ - description: USB4_2 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_0 PHY RX 0 clock source ++ - description: USB4_0 PHY RX 1 clock source ++ - description: USB4_1 PHY RX 0 clock source ++ - description: USB4_1 PHY RX 1 clock source ++ - description: USB4_2 PHY RX 0 clock source ++ - description: USB4_2 PHY RX 1 clock source ++ - description: USB4_0 PHY PCIE PIPE clock source ++ - description: USB4_0 PHY max PIPE clock source ++ - description: USB4_1 PHY PCIE PIPE clock source ++ - description: USB4_1 PHY max PIPE clock source ++ - description: USB4_2 PHY PCIE PIPE clock source ++ - description: USB4_2 PHY max PIPE clock source + + power-domains: + description: +@@ -63,7 +90,34 @@ examples: + <&pcie6b_phy>, + <&usb_1_ss0_qmpphy 0>, + <&usb_1_ss1_qmpphy 1>, +- <&usb_1_ss2_qmpphy 2>; ++ <&usb_1_ss2_qmpphy 2>, ++ <&usb4_0_phy_dp0_gmux_clk>, ++ <&usb4_0_phy_dp1_gmux_clk>, ++ <&usb4_0_phy_pcie_pipegmux_clk>, ++ <&usb4_0_phy_pipegmux_clk>, ++ <&usb4_0_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_1_phy_dp0_gmux_2_clk>, ++ <&usb4_1_phy_dp1_gmux_2_clk>, ++ <&usb4_1_phy_pcie_pipegmux_clk>, ++ <&usb4_1_phy_pipegmux_clk>, ++ <&usb4_1_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_2_phy_dp0_gmux_2_clk>, ++ <&usb4_2_phy_dp1_gmux_2_clk>, ++ <&usb4_2_phy_pcie_pipegmux_clk>, ++ <&usb4_2_phy_pipegmux_clk>, ++ <&usb4_2_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_0_phy_rx_0_clk>, ++ <&usb4_0_phy_rx_1_clk>, ++ <&usb4_1_phy_rx_0_clk>, ++ <&usb4_1_phy_rx_1_clk>, ++ <&usb4_2_phy_rx_0_clk>, ++ <&usb4_2_phy_rx_1_clk>, ++ <&usb4_0_phy_pcie_pipe_clk>, ++ <&usb4_0_phy_max_pipe_clk>, ++ <&usb4_1_phy_pcie_pipe_clk>, ++ <&usb4_1_phy_max_pipe_clk>, ++ <&usb4_2_phy_pcie_pipe_clk>, ++ <&usb4_2_phy_max_pipe_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; + #reset-cells = <1>; +diff --git a/include/dt-bindings/clock/qcom,x1e80100-gcc.h b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +index 710c340f24a57..62aa124255927 100644 +--- a/include/dt-bindings/clock/qcom,x1e80100-gcc.h ++++ b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +@@ -363,6 +363,30 @@ + #define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 353 + #define GCC_USB3_SEC_PHY_PIPE_CLK_SRC 354 + #define GCC_USB3_TERT_PHY_PIPE_CLK_SRC 355 ++#define GCC_USB34_PRIM_PHY_PIPE_CLK_SRC 356 ++#define GCC_USB34_SEC_PHY_PIPE_CLK_SRC 357 ++#define GCC_USB34_TERT_PHY_PIPE_CLK_SRC 358 ++#define GCC_USB4_0_PHY_DP0_CLK_SRC 359 ++#define GCC_USB4_0_PHY_DP1_CLK_SRC 360 ++#define GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC 361 ++#define GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC 362 ++#define GCC_USB4_0_PHY_RX0_CLK_SRC 363 ++#define GCC_USB4_0_PHY_RX1_CLK_SRC 364 ++#define GCC_USB4_0_PHY_SYS_CLK_SRC 365 ++#define GCC_USB4_1_PHY_DP0_CLK_SRC 366 ++#define GCC_USB4_1_PHY_DP1_CLK_SRC 367 ++#define GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC 368 ++#define GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC 369 ++#define GCC_USB4_1_PHY_RX0_CLK_SRC 370 ++#define GCC_USB4_1_PHY_RX1_CLK_SRC 371 ++#define GCC_USB4_1_PHY_SYS_CLK_SRC 372 ++#define GCC_USB4_2_PHY_DP0_CLK_SRC 373 ++#define GCC_USB4_2_PHY_DP1_CLK_SRC 374 ++#define GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC 375 ++#define GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC 376 ++#define GCC_USB4_2_PHY_RX0_CLK_SRC 377 ++#define GCC_USB4_2_PHY_RX1_CLK_SRC 378 ++#define GCC_USB4_2_PHY_SYS_CLK_SRC 379 + + /* GCC power domains */ + #define GCC_PCIE_0_TUNNEL_GDSC 0 +@@ -484,4 +508,41 @@ + #define GCC_VIDEO_BCR 87 + #define GCC_VIDEO_AXI0_CLK_ARES 88 + #define GCC_VIDEO_AXI1_CLK_ARES 89 ++#define GCC_USB4_0_MISC_USB4_SYS_BCR 90 ++#define GCC_USB4_0_MISC_RX_CLK_0_BCR 91 ++#define GCC_USB4_0_MISC_RX_CLK_1_BCR 92 ++#define GCC_USB4_0_MISC_USB_PIPE_BCR 93 ++#define GCC_USB4_0_MISC_PCIE_PIPE_BCR 94 ++#define GCC_USB4_0_MISC_TMU_BCR 95 ++#define GCC_USB4_0_MISC_SB_IF_BCR 96 ++#define GCC_USB4_0_MISC_HIA_MSTR_BCR 97 ++#define GCC_USB4_0_MISC_AHB_BCR 98 ++#define GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR 99 ++#define GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR 100 ++#define GCC_USB4_1_MISC_USB4_SYS_BCR 101 ++#define GCC_USB4_1_MISC_RX_CLK_0_BCR 102 ++#define GCC_USB4_1_MISC_RX_CLK_1_BCR 103 ++#define GCC_USB4_1_MISC_USB_PIPE_BCR 104 ++#define GCC_USB4_1_MISC_PCIE_PIPE_BCR 105 ++#define GCC_USB4_1_MISC_TMU_BCR 106 ++#define GCC_USB4_1_MISC_SB_IF_BCR 107 ++#define GCC_USB4_1_MISC_HIA_MSTR_BCR 108 ++#define GCC_USB4_1_MISC_AHB_BCR 109 ++#define GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR 110 ++#define GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR 111 ++#define GCC_USB4_2_MISC_USB4_SYS_BCR 112 ++#define GCC_USB4_2_MISC_RX_CLK_0_BCR 113 ++#define GCC_USB4_2_MISC_RX_CLK_1_BCR 114 ++#define GCC_USB4_2_MISC_USB_PIPE_BCR 115 ++#define GCC_USB4_2_MISC_PCIE_PIPE_BCR 116 ++#define GCC_USB4_2_MISC_TMU_BCR 117 ++#define GCC_USB4_2_MISC_SB_IF_BCR 118 ++#define GCC_USB4_2_MISC_HIA_MSTR_BCR 119 ++#define GCC_USB4_2_MISC_AHB_BCR 120 ++#define GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR 121 ++#define GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR 122 ++#define GCC_USB4PHY_PHY_PRIM_BCR 123 ++#define GCC_USB4PHY_PHY_SEC_BCR 124 ++#define GCC_USB4PHY_PHY_TERT_BCR 125 ++ + #endif +-- +2.51.0 + diff --git a/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-vide.patch b/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-vide.patch new file mode 100644 index 0000000000..6127350a3f --- /dev/null +++ b/queue-6.12/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-vide.patch @@ -0,0 +1,36 @@ +From 5eece7f1d12bd9d9345b70b2e21f4f78d6e5579a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Jul 2025 12:08:56 +0200 +Subject: dt-bindings: clock: qcom,x1e80100-gcc: Add missing video resets + +From: Stephan Gerhold + +[ Upstream commit d0b706509fb04449add5446e51a494bfeadcac10 ] + +Add the missing video resets that are needed for the iris video codec. + +Acked-by: Rob Herring (Arm) +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Stephan Gerhold +Link: https://lore.kernel.org/r/20250709-x1e-videocc-v2-4-ad1acf5674b4@linaro.org +Signed-off-by: Bjorn Andersson +Stable-dep-of: 8abe970efea5 ("clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets") +Signed-off-by: Sasha Levin +--- + include/dt-bindings/clock/qcom,x1e80100-gcc.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/dt-bindings/clock/qcom,x1e80100-gcc.h b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +index 24ba9e2a5cf6c..710c340f24a57 100644 +--- a/include/dt-bindings/clock/qcom,x1e80100-gcc.h ++++ b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +@@ -482,4 +482,6 @@ + #define GCC_USB_1_PHY_BCR 85 + #define GCC_USB_2_PHY_BCR 86 + #define GCC_VIDEO_BCR 87 ++#define GCC_VIDEO_AXI0_CLK_ARES 88 ++#define GCC_VIDEO_AXI1_CLK_ARES 89 + #endif +-- +2.51.0 + diff --git a/queue-6.12/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-6.12/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..6a99c595bb --- /dev/null +++ b/queue-6.12/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From d918bb1a5287778fd058c75d52db06c6339ecdc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index 79a21ba0f9fd6..c8258ef403283 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-6.12/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch b/queue-6.12/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch new file mode 100644 index 0000000000..03b158b95c --- /dev/null +++ b/queue-6.12/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch @@ -0,0 +1,71 @@ +From 701849229bb4aefc8884610b24c93905d6ee181f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:23 +0000 +Subject: efi/libstub: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit 84361123413efc84b06f3441c6c827b95d902732 ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags Bits above the + physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The pgd value is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c +index 77359e802181f..c0f317b55c4bb 100644 +--- a/drivers/firmware/efi/libstub/x86-5lvl.c ++++ b/drivers/firmware/efi/libstub/x86-5lvl.c +@@ -66,7 +66,7 @@ void efi_5level_switch(void) + bool have_la57 = native_read_cr4() & X86_CR4_LA57; + bool need_toggle = want_la57 ^ have_la57; + u64 *pgt = (void *)la57_toggle + PAGE_SIZE; +- u64 *cr3 = (u64 *)__native_read_cr3(); ++ pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); + u64 *new_cr3; + + if (!la57_toggle || !need_toggle) +@@ -82,7 +82,7 @@ void efi_5level_switch(void) + new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; + } else { + /* take the new root table pointer from the current entry #0 */ +- new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); ++ new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); + + /* copy the new root table if it is not 32-bit addressable */ + if ((u64)new_cr3 > U32_MAX) +-- +2.51.0 + diff --git a/queue-6.12/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch b/queue-6.12/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch new file mode 100644 index 0000000000..ead75015ee --- /dev/null +++ b/queue-6.12/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch @@ -0,0 +1,52 @@ +From 31986d934056c3d06bbf64828bf0fd3fcb81ca10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 14:23:32 +0800 +Subject: erofs: limit the level of fs stacking for file-backed mounts + +From: Gao Xiang + +[ Upstream commit d53cd891f0e4311889349fff3a784dc552f814b9 ] + +Otherwise, it could cause potential kernel stack overflow (e.g., EROFS +mounting itself). + +Reviewed-by: Sheng Yong +Fixes: fb176750266a ("erofs: add file-backed mount support") +Reviewed-by: Chao Yu +Reviewed-by: Hongbo Li +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/super.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/fs/erofs/super.c b/fs/erofs/super.c +index 5fcdab6145176..027fd567a4d9f 100644 +--- a/fs/erofs/super.c ++++ b/fs/erofs/super.c +@@ -636,6 +636,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) + + sbi->blkszbits = PAGE_SHIFT; + if (!sb->s_bdev) { ++ /* ++ * (File-backed mounts) EROFS claims it's safe to nest other ++ * fs contexts (including its own) due to self-controlled RO ++ * accesses/contexts and no side-effect changes that need to ++ * context save & restore so it can reuse the current thread ++ * context. However, it still needs to bump `s_stack_depth` to ++ * avoid kernel stack overflow from nested filesystems. ++ */ ++ if (erofs_is_fileio_mode(sbi)) { ++ sb->s_stack_depth = ++ file_inode(sbi->dif0.file)->i_sb->s_stack_depth + 1; ++ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { ++ erofs_err(sb, "maximum fs stacking depth exceeded"); ++ return -ENOTBLK; ++ } ++ } + sb->s_blocksize = PAGE_SIZE; + sb->s_blocksize_bits = PAGE_SHIFT; + +-- +2.51.0 + diff --git a/queue-6.12/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-6.12/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..2e6d2fcbd4 --- /dev/null +++ b/queue-6.12/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From f4216c161fbed25df3522642ed25ba512c2e6146 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index a4c94eabc78ec..dfd7958899288 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -487,7 +487,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-6.12/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-6.12/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..4fdac17cc5 --- /dev/null +++ b/queue-6.12/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From ac1aa13be7f643a55b75e9bf16937cdec6806548 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 76331cdb4cb51..96bb2d2366d6e 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -677,6 +677,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -718,15 +736,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -742,15 +751,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-6.12/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-6.12/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..038b902236 --- /dev/null +++ b/queue-6.12/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From 93000cefa3bf5f1b6210c090d366a82181fcb9d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index aa6cc0a8151ac..83dd31fa1fab5 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -680,7 +680,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -757,6 +757,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-6.12/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-6.12/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..76a163e4e4 --- /dev/null +++ b/queue-6.12/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From fb78c3e3ba7128ffbc7f1f3ca622e51a5e515316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index 6125cccc9ba79..f2b902e95b738 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-6.12/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch b/queue-6.12/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch new file mode 100644 index 0000000000..2edc4f0b8d --- /dev/null +++ b/queue-6.12/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch @@ -0,0 +1,59 @@ +From 635d9cd9229ccf8086c4570205e7c2b68fdd9a6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 12:13:23 -0700 +Subject: firmware: qcom: tzmem: fix qcom_tzmem_policy kernel-doc + +From: Randy Dunlap + +[ Upstream commit edd548dc64a699d71ea4f537f815044e763d01e1 ] + +Fix kernel-doc warnings by using correct kernel-doc syntax and +formatting to prevent warnings: + +Warning: include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_STATIC' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_MULTIPLIER' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_ON_DEMAND' not described in enum 'qcom_tzmem_policy' + +Fixes: 84f5a7b67b61 ("firmware: qcom: add a dedicated TrustZone buffer allocator") +Signed-off-by: Randy Dunlap +Link: https://lore.kernel.org/r/20251017191323.1820167-1-rdunlap@infradead.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + include/linux/firmware/qcom/qcom_tzmem.h | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h +index b83b63a0c049b..e1e26dc4180e7 100644 +--- a/include/linux/firmware/qcom/qcom_tzmem.h ++++ b/include/linux/firmware/qcom/qcom_tzmem.h +@@ -17,11 +17,20 @@ struct qcom_tzmem_pool; + * enum qcom_tzmem_policy - Policy for pool growth. + */ + enum qcom_tzmem_policy { +- /**< Static pool, never grow above initial size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_STATIC: Static pool, ++ * never grow above initial size. ++ */ + QCOM_TZMEM_POLICY_STATIC = 1, +- /**< When out of memory, add increment * current size of memory. */ ++ /** ++ * @QCOM_TZMEM_POLICY_MULTIPLIER: When out of memory, ++ * add increment * current size of memory. ++ */ + QCOM_TZMEM_POLICY_MULTIPLIER, +- /**< When out of memory add as much as is needed until max_size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_ON_DEMAND: When out of memory ++ * add as much as is needed until max_size. ++ */ + QCOM_TZMEM_POLICY_ON_DEMAND, + }; + +-- +2.51.0 + diff --git a/queue-6.12/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch b/queue-6.12/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch new file mode 100644 index 0000000000..73ec89d5fa --- /dev/null +++ b/queue-6.12/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch @@ -0,0 +1,40 @@ +From e5701e582950becfcbd23a53cba462c615554b93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:58:13 -0600 +Subject: firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc + +From: Dinh Nguyen + +[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ] + +Fix this warning that was generated from "make htmldocs": + +WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' +not described in 'stratix10_svc' + +Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ +Signed-off-by: Dinh Nguyen +Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/stratix10-svc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index 554b6b95187b4..4627a00a5590b 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -52,6 +52,7 @@ struct stratix10_svc_chan; + /** + * struct stratix10_svc - svc private data + * @stratix10_svc_rsu: pointer to stratix10 RSU device ++ * @intel_svc_fcs: pointer to the FCS device + */ + struct stratix10_svc { + struct platform_device *stratix10_svc_rsu; +-- +2.51.0 + diff --git a/queue-6.12/firmware_loader-make-rust_fw_loader_abstractions-sel.patch b/queue-6.12/firmware_loader-make-rust_fw_loader_abstractions-sel.patch new file mode 100644 index 0000000000..f9c38ed33f --- /dev/null +++ b/queue-6.12/firmware_loader-make-rust_fw_loader_abstractions-sel.patch @@ -0,0 +1,38 @@ +From 1913080bc67f10d5bee2fcf2864a648d684ac10f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 11:40:54 +0900 +Subject: firmware_loader: make RUST_FW_LOADER_ABSTRACTIONS select FW_LOADER + +From: Alexandre Courbot + +[ Upstream commit 9906efa545d1d2cf25a614eeb219d3f8d5a302cd ] + +The use of firmware_loader is an implementation detail of drivers rather +than a dependency. FW_LOADER is typically selected rather than depended +on; the Rust abstractions should do the same thing. + +Fixes: de6582833db0 ("rust: add firmware abstractions") +Signed-off-by: Alexandre Courbot +Link: https://patch.msgid.link/20251106-b4-select-rust-fw-v3-1-771172257755@nvidia.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/base/firmware_loader/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig +index a037016742651..4bf593fb253ac 100644 +--- a/drivers/base/firmware_loader/Kconfig ++++ b/drivers/base/firmware_loader/Kconfig +@@ -40,7 +40,7 @@ config FW_LOADER_DEBUG + config RUST_FW_LOADER_ABSTRACTIONS + bool "Rust Firmware Loader abstractions" + depends on RUST +- depends on FW_LOADER=y ++ select FW_LOADER + help + This enables the Rust abstractions for the firmware loader API. + +-- +2.51.0 + diff --git a/queue-6.12/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch b/queue-6.12/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch new file mode 100644 index 0000000000..b3693bb784 --- /dev/null +++ b/queue-6.12/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch @@ -0,0 +1,104 @@ +From d633272d95d07f37ae9688c86319483282dbf33f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 23:56:30 +0000 +Subject: fs/9p: Don't open remote file with APPEND mode when writeback cache + is used + +From: Tingmao Wang + +[ Upstream commit a63dd8fd137933551bfd9aeeeaa942f04c7aad65 ] + +When page cache is used, writebacks are done on a page granularity, and it +is expected that the underlying filesystem (such as v9fs) should respect +the write position. However, currently v9fs will passthrough O_APPEND to +the server even on cached mode. This causes data corruption if a sync or +fstat gets between two writes to the same file. + +This patch removes the APPEND flag from the open request we send to the +server when writeback caching is involved. I believe keeping server-side +APPEND is probably fine for uncached mode (even if two fds are opened, one +without O_APPEND and one with it, this should still be fine since they +would use separate fid for the writes). + +Signed-off-by: Tingmao Wang +Fixes: 4eb3117888a9 ("fs/9p: Rework cache modes and add new options to Documentation") +Message-ID: <20251102235631.8724-1-m@maowtm.org> +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/vfs_file.c | 11 ++++++++--- + fs/9p/vfs_inode.c | 3 +-- + fs/9p/vfs_inode_dotl.c | 2 +- + 3 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c +index 348cc90bf9c56..de0d1f74de46c 100644 +--- a/fs/9p/vfs_file.c ++++ b/fs/9p/vfs_file.c +@@ -43,14 +43,18 @@ int v9fs_file_open(struct inode *inode, struct file *file) + struct v9fs_session_info *v9ses; + struct p9_fid *fid; + int omode; ++ int o_append; + + p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); + v9ses = v9fs_inode2v9ses(inode); +- if (v9fs_proto_dotl(v9ses)) ++ if (v9fs_proto_dotl(v9ses)) { + omode = v9fs_open_to_dotl_flags(file->f_flags); +- else ++ o_append = P9_DOTL_APPEND; ++ } else { + omode = v9fs_uflags2omode(file->f_flags, + v9fs_proto_dotu(v9ses)); ++ o_append = P9_OAPPEND; ++ } + fid = file->private_data; + if (!fid) { + fid = v9fs_fid_clone(file_dentry(file)); +@@ -58,9 +62,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) + return PTR_ERR(fid); + + if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { +- int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; ++ int writeback_omode = (omode & ~(P9_OWRITE | o_append)) | P9_ORDWR; + + p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); ++ + err = p9_client_open(fid, writeback_omode); + if (err < 0) { + p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index 3e68521f4e2f9..1723a37d1846e 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -791,7 +791,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, + p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_OAPPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +@@ -1404,4 +1404,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = { + .getattr = v9fs_vfs_getattr, + .setattr = v9fs_vfs_setattr, + }; +- +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index 3397939fd2d5a..40a4fc65a5441 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -286,7 +286,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, + } + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_DOTL_APPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-6.12/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..4720a82a20 --- /dev/null +++ b/queue-6.12/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From 67d71560019543c5cdaafb098bcd6cd8d2da968c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index ed38014d17505..ec2be861db33d 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1069,9 +1069,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-6.12/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-6.12/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..d11d095711 --- /dev/null +++ b/queue-6.12/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From 128e9eb6dda1e1ea9b69061b75b4cf993899cdc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index ec2be861db33d..5491169eaa16c 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -380,8 +380,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.12/gfs2-prevent-recursive-memory-reclaim.patch b/queue-6.12/gfs2-prevent-recursive-memory-reclaim.patch new file mode 100644 index 0000000000..19f58cd43e --- /dev/null +++ b/queue-6.12/gfs2-prevent-recursive-memory-reclaim.patch @@ -0,0 +1,135 @@ +From 4121c0429833578739e9d085344f1c71a046f153 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:05:37 +0000 +Subject: gfs2: Prevent recursive memory reclaim + +From: Andreas Gruenbacher + +[ Upstream commit 2c5f4a53476e3cab70adc77b38942c066bd2c17c ] + +Function new_inode() returns a new inode with inode->i_mapping->gfp_mask +set to GFP_HIGHUSER_MOVABLE. This value includes the __GFP_FS flag, so +allocations in that address space can recurse into filesystem memory +reclaim. We don't want that to happen because it can consume a +significant amount of stack memory. + +Worse than that is that it can also deadlock: for example, in several +places, gfs2_unstuff_dinode() is called inside filesystem transactions. +This calls filemap_grab_folio(), which can allocate a new folio, which +can trigger memory reclaim. If memory reclaim recurses into the +filesystem and starts another transaction, a deadlock will ensue. + +To fix these kinds of problems, prevent memory reclaim from recursing +into filesystem code by making sure that the gfp_mask of inode address +spaces doesn't include __GFP_FS. + +The "meta" and resource group address spaces were already using GFP_NOFS +as their gfp_mask (which doesn't include __GFP_FS). The default value +of GFP_HIGHUSER_MOVABLE is less restrictive than GFP_NOFS, though. To +avoid being overly limiting, use the default value and only knock off +the __GFP_FS flag. I'm not sure if this will actually make a +difference, but it also shouldn't hurt. + +This patch is loosely based on commit ad22c7a043c2 ("xfs: prevent stack +overflows from page cache allocation"). + +Fixes xfstest generic/273. + +Fixes: dc0b9435238c ("gfs: Don't use GFP_NOFS in gfs2_unstuff_dinode") +Reviewed-by: Andrew Price +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glock.c | 5 ++++- + fs/gfs2/inode.c | 15 +++++++++++++++ + fs/gfs2/inode.h | 1 + + fs/gfs2/ops_fstype.c | 2 +- + 4 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index e5558e63e2cba..54d0eee24e10b 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -1250,10 +1250,13 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, + + mapping = gfs2_glock2aspace(gl); + if (mapping) { ++ gfp_t gfp_mask; ++ + mapping->a_ops = &gfs2_meta_aops; + mapping->host = sdp->sd_inode; + mapping->flags = 0; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfp_mask = mapping_gfp_mask(sdp->sd_inode->i_mapping); ++ mapping_set_gfp_mask(mapping, gfp_mask); + mapping->i_private_data = NULL; + mapping->writeback_index = 0; + } +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 0b546024f5ef7..90c7a795112d6 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -89,6 +89,19 @@ static int iget_set(struct inode *inode, void *opaque) + return 0; + } + ++void gfs2_setup_inode(struct inode *inode) ++{ ++ gfp_t gfp_mask; ++ ++ /* ++ * Ensure all page cache allocations are done from GFP_NOFS context to ++ * prevent direct reclaim recursion back into the filesystem and blowing ++ * stacks or deadlocking. ++ */ ++ gfp_mask = mapping_gfp_mask(inode->i_mapping); ++ mapping_set_gfp_mask(inode->i_mapping, gfp_mask & ~__GFP_FS); ++} ++ + /** + * gfs2_inode_lookup - Lookup an inode + * @sb: The super block +@@ -132,6 +145,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, + struct gfs2_glock *io_gl; + int extra_flags = 0; + ++ gfs2_setup_inode(inode); + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, + &ip->i_gl); + if (unlikely(error)) +@@ -754,6 +768,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, + error = -ENOMEM; + if (!inode) + goto fail_gunlock; ++ gfs2_setup_inode(inode); + ip = GFS2_I(inode); + + error = posix_acl_create(dir, &mode, &default_acl, &acl); +diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h +index 225b9d0038cd0..136b231a17f8d 100644 +--- a/fs/gfs2/inode.h ++++ b/fs/gfs2/inode.h +@@ -86,6 +86,7 @@ static inline int gfs2_check_internal_file_size(struct inode *inode, + return -EIO; + } + ++void gfs2_setup_inode(struct inode *inode); + struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, + u64 no_addr, u64 no_formal_ino, + unsigned int blktype); +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index 4a0f7de41b2b2..4c6d1f15a6a84 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -1185,7 +1185,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) + + mapping = gfs2_aspace(sdp); + mapping->a_ops = &gfs2_rgrp_aops; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfs2_setup_inode(sdp->sd_inode); + + error = init_names(sdp, silent); + if (error) +-- +2.51.0 + diff --git a/queue-6.12/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-6.12/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..42a9b63d2a --- /dev/null +++ b/queue-6.12/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 3cda2f982653d941abd5f34fda2a832f5c18091c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index f63d14a57a1d9..acc7d82e0585e 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -345,8 +345,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -369,7 +367,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-6.12/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch b/queue-6.12/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch new file mode 100644 index 0000000000..a6243a7def --- /dev/null +++ b/queue-6.12/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch @@ -0,0 +1,66 @@ +From a846627e3351c30811394dae005ff6dcbdb4ee0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:40:27 +0800 +Subject: greybus: gb-beagleplay: Fix timeout handling in bootloader functions + +From: Haotian Zhang + +[ Upstream commit e6df0f649cff08da7a2feb6d963b39076ca129f9 ] + +wait_for_completion_timeout() returns the remaining jiffies +(at least 1) on success or 0 on timeout, but never negative +error codes. The current code incorrectly checks for negative +values, causing timeouts to be ignored and treated as success. + +Check for a zero return value to correctly identify and +handle timeout events. + +Fixes: 0cf7befa3ea2 ("greybus: gb-beagleplay: Add firmware upload API") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251121064027.571-1-vulab@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/greybus/gb-beagleplay.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c +index da31f1131afca..2a207eab40452 100644 +--- a/drivers/greybus/gb-beagleplay.c ++++ b/drivers/greybus/gb-beagleplay.c +@@ -644,8 +644,8 @@ static int cc1352_bootloader_wait_for_ack(struct gb_beagleplay *bg) + + ret = wait_for_completion_timeout( + &bg->fwl_ack_com, msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire ack semaphore"); + + switch (READ_ONCE(bg->fwl_ack)) { +@@ -683,8 +683,8 @@ static int cc1352_bootloader_get_status(struct gb_beagleplay *bg) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + switch (READ_ONCE(bg->fwl_cmd_response)) { +@@ -768,8 +768,8 @@ static int cc1352_bootloader_crc32(struct gb_beagleplay *bg, u32 *crc32) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + *crc32 = READ_ONCE(bg->fwl_cmd_response); +-- +2.51.0 + diff --git a/queue-6.12/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch b/queue-6.12/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch new file mode 100644 index 0000000000..762393fff7 --- /dev/null +++ b/queue-6.12/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch @@ -0,0 +1,59 @@ +From e7caa0acf5e43c9763f68013bc467d99601474d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 19:30:58 +0000 +Subject: HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync() + +From: Mavroudis Chatzilazaridis + +[ Upstream commit aba7963544d47d82cdf36602a6678a093af0299d ] + +Currently, hidpp_send_message_sync() retries sending the message when the +device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which +has a different meaning under RAP. This ends up being a problem because +this function is used for both FAP and RAP messages. + +This issue is not noticeable on older receivers with unreachable devices +since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to +HIDPP20_ERROR_BUSY (0x08). + +However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which +happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when +the device is not actually busy. + +This is resolved by checking if the error response is FAP or RAP and +picking the respective ERROR_BUSY code. + +Fixes: 60165ab774cb ("HID: logitech-hidpp: rework one more time the retries attempts") +Signed-off-by: Mavroudis Chatzilazaridis +Tested-by: Stuart Hayhurst +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 2e72e8967e685..7d5bf5991fc6a 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -352,10 +352,15 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, + + do { + ret = __do_hidpp_send_message_sync(hidpp, message, response); +- if (ret != HIDPP20_ERROR_BUSY) ++ if (response->report_id == REPORT_ID_HIDPP_SHORT && ++ ret != HIDPP_ERROR_BUSY) ++ break; ++ if ((response->report_id == REPORT_ID_HIDPP_LONG || ++ response->report_id == REPORT_ID_HIDPP_VERY_LONG) && ++ ret != HIDPP20_ERROR_BUSY) + break; + +- dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret); ++ dbg_hid("%s:got busy hidpp error %02X, retrying\n", __func__, ret); + } while (--max_retries); + + mutex_unlock(&hidpp->send_mutex); +-- +2.51.0 + diff --git a/queue-6.12/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch b/queue-6.12/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch new file mode 100644 index 0000000000..fed9de592c --- /dev/null +++ b/queue-6.12/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch @@ -0,0 +1,54 @@ +From c4f238ca044b1e34dbcf9263e7e573109a19d5a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 00:26:02 +0800 +Subject: hwmon: sy7636a: Fix regulator_enable resource leak on error path + +From: Haotian Zhang + +[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ] + +In sy7636a_sensor_probe(), regulator_enable() is called but if +devm_hwmon_device_register_with_info() fails, the function returns +without calling regulator_disable(), leaving the regulator enabled +and leaking the reference count. + +Switch to devm_regulator_get_enable() to automatically +manage the regulator resource. + +Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sy7636a-hwmon.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c +index a12fc0ce70e76..d51daaf63d632 100644 +--- a/drivers/hwmon/sy7636a-hwmon.c ++++ b/drivers/hwmon/sy7636a-hwmon.c +@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { + static int sy7636a_sensor_probe(struct platform_device *pdev) + { + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); +- struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + +- regulator = devm_regulator_get(&pdev->dev, "vcom"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); ++ err = devm_regulator_get_enable(&pdev->dev, "vcom"); + if (err) + return err; + +-- +2.51.0 + diff --git a/queue-6.12/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-6.12/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..98149432f6 --- /dev/null +++ b/queue-6.12/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From 057c636a8c3730778d2d8fa50a65d98372e20e74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index c8e5c9291ea43..6eb779affaba8 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2809,10 +2809,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2820,6 +2816,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.12/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-6.12/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..151891e402 --- /dev/null +++ b/queue-6.12/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From 1a8cfad57f49bdc86dd47324f021916ce8fd139d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index a1945bf9ef19e..985f30ef0c939 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -366,21 +366,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-6.12/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-6.12/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..b4665338ef --- /dev/null +++ b/queue-6.12/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From c985d7bc92a6b691c0a0ef54df7951fd1edd2373 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index b4c6c31df837e..e9af7881e190d 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -383,7 +383,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-6.12/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-6.12/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..1685da65e1 --- /dev/null +++ b/queue-6.12/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From a60550178166c4e29ae831500e49e0b1b543cb54 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 09da8e6392395..11b3ea1099ba3 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -672,7 +672,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..88ba5024e0 --- /dev/null +++ b/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From 735f849e04dc88db0c1b94ee345c7f96dfd29ed6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 722f409cccd35..6edd9cac50067 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -829,6 +829,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 2b4a588247639..37a6acff537e6 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -671,8 +671,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -681,6 +684,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch b/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch new file mode 100644 index 0000000000..a53c10765a --- /dev/null +++ b/queue-6.12/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch @@ -0,0 +1,117 @@ +From 62359723f8faa76ad561c2efbc67b6fc5776e224 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:36 +0800 +Subject: inet: Avoid ehash lookup race in inet_twsk_hashdance_schedule() + +From: Xuanqiang Luo + +[ Upstream commit b8ec80b130211e7bf076ef72365952979d5f7a72 ] + +Since ehash lookups are lockless, if another CPU is converting sk to tw +concurrently, fetching the newly inserted tw with tw->tw_refcnt == 0 cause +lookup failure. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_twsk_hashdance_schedule() + spin_lock() + inet_twsk_add_node_rcu(tw, ...) +__inet_lookup_established() +(find tw, failure due to tw_refcnt = 0) + __sk_nulls_del_node_init_rcu(sk) + refcount_set(&tw->tw_refcnt, 3) + spin_unlock() + +By replacing sk with tw atomically via hlist_nulls_replace_init_rcu() after +setting tw_refcnt, we ensure that tw is either fully initialized or not +visible to other CPUs, eliminating the race. + +It's worth noting that we held lock_sock() before the replacement, so +there's no need to check if sk is hashed. Thanks to Kuniyuki Iwashima! + +Fixes: 3ab5aee7fe84 ("net: Convert TCP & DCCP hash tables to use RCU / hlist_nulls") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-4-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_timewait_sock.c | 35 ++++++++++++----------------------- + 1 file changed, 12 insertions(+), 23 deletions(-) + +diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c +index 337390ba85b40..74b84ac418e93 100644 +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -86,12 +86,6 @@ void inet_twsk_put(struct inet_timewait_sock *tw) + } + EXPORT_SYMBOL_GPL(inet_twsk_put); + +-static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, +- struct hlist_nulls_head *list) +-{ +- hlist_nulls_add_head_rcu(&tw->tw_node, list); +-} +- + static void inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo) + { + __inet_twsk_schedule(tw, timeo, false); +@@ -111,13 +105,12 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + { + const struct inet_sock *inet = inet_sk(sk); + const struct inet_connection_sock *icsk = inet_csk(sk); +- struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash); + spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash); + struct inet_bind_hashbucket *bhead, *bhead2; + +- /* Step 1: Put TW into bind hash. Original socket stays there too. +- Note, that any socket with inet->num != 0 MUST be bound in +- binding cache, even if it is closed. ++ /* Put TW into bind hash. Original socket stays there too. ++ * Note, that any socket with inet->num != 0 MUST be bound in ++ * binding cache, even if it is closed. + */ + bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num, + hashinfo->bhash_size)]; +@@ -139,19 +132,6 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + + spin_lock(lock); + +- /* Step 2: Hash TW into tcp ehash chain */ +- inet_twsk_add_node_rcu(tw, &ehead->chain); +- +- /* Step 3: Remove SK from hash chain */ +- if (__sk_nulls_del_node_init_rcu(sk)) +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +- +- +- /* Ensure above writes are committed into memory before updating the +- * refcount. +- * Provides ordering vs later refcount_inc(). +- */ +- smp_wmb(); + /* tw_refcnt is set to 3 because we have : + * - one reference for bhash chain. + * - one reference for ehash chain. +@@ -161,6 +141,15 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + */ + refcount_set(&tw->tw_refcnt, 3); + ++ /* Ensure tw_refcnt has been set before tw is published. ++ * smp_wmb() provides the necessary memory barrier to enforce this ++ * ordering. ++ */ ++ smp_wmb(); ++ ++ hlist_nulls_replace_init_rcu(&sk->sk_nulls_node, &tw->tw_node); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ + inet_twsk_schedule(tw, timeo); + + spin_unlock(lock); +-- +2.51.0 + diff --git a/queue-6.12/interconnect-debugfs-fix-incorrect-error-handling-fo.patch b/queue-6.12/interconnect-debugfs-fix-incorrect-error-handling-fo.patch new file mode 100644 index 0000000000..4c5104acdf --- /dev/null +++ b/queue-6.12/interconnect-debugfs-fix-incorrect-error-handling-fo.patch @@ -0,0 +1,53 @@ +From c96361786d48a7b2843ee29405fbc333d29569bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 23:14:47 +0800 +Subject: interconnect: debugfs: Fix incorrect error handling for NULL path + +From: Kuan-Wei Chiu + +[ Upstream commit 6bfe104fd0f94d0248af22c256ce725ee087157b ] + +The icc_commit_set() function, used by the debugfs interface, checks +the validity of the global cur_path pointer using IS_ERR_OR_NULL(). +However, in the specific case where cur_path is NULL, while +IS_ERR_OR_NULL(NULL) correctly evaluates to true, the subsequent call +to PTR_ERR(NULL) returns 0. + +This causes the function to return a success code (0) instead of an +error, misleading the user into believing their bandwidth request was +successfully committed when, in fact, no operation was performed. + +Fix this by adding an explicit check to return -EINVAL if cur_path is +NULL. This prevents silent failures and ensures that an invalid +operational sequence is immediately and clearly reported as an error. + +Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") +Signed-off-by: Kuan-Wei Chiu +Link: https://lore.kernel.org/r/20251010151447.2289779-1-visitorckw@gmail.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/debugfs-client.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c +index bc3fd8a7b9eb4..778deeb4a7e8a 100644 +--- a/drivers/interconnect/debugfs-client.c ++++ b/drivers/interconnect/debugfs-client.c +@@ -117,7 +117,12 @@ static int icc_commit_set(void *data, u64 val) + + mutex_lock(&debugfs_lock); + +- if (IS_ERR_OR_NULL(cur_path)) { ++ if (!cur_path) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (IS_ERR(cur_path)) { + ret = PTR_ERR(cur_path); + goto out; + } +-- +2.51.0 + diff --git a/queue-6.12/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch b/queue-6.12/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch new file mode 100644 index 0000000000..05a2635427 --- /dev/null +++ b/queue-6.12/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch @@ -0,0 +1,38 @@ +From 9fc63b81af496fb1c34ed876fe22ca9191b6aea4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:00 +0300 +Subject: interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS + +From: Dmitry Baryshkov + +[ Upstream commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 ] + +>From the initial submission the interconnect driver missed the link from +SNOC_PNOC to the USB 2 configuration space. Add missing link in order to +let the platform configure and utilize this path. + +Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/msm8996.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c +index 788131400cd13..6c8c6e974c811 100644 +--- a/drivers/interconnect/qcom/msm8996.c ++++ b/drivers/interconnect/qcom/msm8996.c +@@ -552,6 +552,7 @@ static struct qcom_icc_node mas_venus_vmem = { + static const u16 mas_snoc_pnoc_links[] = { + MSM8996_SLAVE_BLSP_1, + MSM8996_SLAVE_BLSP_2, ++ MSM8996_SLAVE_USB_HS, + MSM8996_SLAVE_SDCC_1, + MSM8996_SLAVE_SDCC_2, + MSM8996_SLAVE_SDCC_4, +-- +2.51.0 + diff --git a/queue-6.12/iomap-always-run-error-completions-in-user-context.patch b/queue-6.12/iomap-always-run-error-completions-in-user-context.patch new file mode 100644 index 0000000000..d04c3a78ea --- /dev/null +++ b/queue-6.12/iomap-always-run-error-completions-in-user-context.patch @@ -0,0 +1,51 @@ +From fd7245d9eeae590f8f11f4b7565de10b644a6fc4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:06:27 +0100 +Subject: iomap: always run error completions in user context + +From: Christoph Hellwig + +[ Upstream commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a ] + +At least zonefs expects error completions to be able to sleep. Because +error completions aren't performance critical, just defer them to workqueue +context unconditionally. + +Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251113170633.1453259-3-hch@lst.de +Reviewed-by: Jan Kara +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index 5209f0ec7427d..aba9d5ce819d0 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -179,7 +179,18 @@ static void iomap_dio_done(struct iomap_dio *dio) + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ return; ++ } ++ ++ /* ++ * Always run error completions in user context. These are not ++ * performance critical and some code relies on taking sleeping locks ++ * for error handling. ++ */ ++ if (dio->error) ++ dio->flags &= ~IOMAP_DIO_INLINE_COMP; ++ ++ if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); + } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { +-- +2.51.0 + diff --git a/queue-6.12/iomap-factor-out-a-iomap_dio_done-helper.patch b/queue-6.12/iomap-factor-out-a-iomap_dio_done-helper.patch new file mode 100644 index 0000000000..eba7d333bc --- /dev/null +++ b/queue-6.12/iomap-factor-out-a-iomap_dio_done-helper.patch @@ -0,0 +1,132 @@ +From b1c3f8231466813d22712faeaef58c8ecc7cf2a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 07:40:04 +0100 +Subject: iomap: factor out a iomap_dio_done helper + +From: Christoph Hellwig + +[ Upstream commit ae2f33a519af3730cacd1c787ebe1f7475df5ba8 ] + +Split out the struct iomap-dio level final completion from +iomap_dio_bio_end_io into a helper to clean up the code and make it +reusable. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20250206064035.2323428-7-hch@lst.de +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Christian Brauner +Stable-dep-of: ddb4873286e0 ("iomap: always run error completions in user context") +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 76 ++++++++++++++++++++++---------------------- + 1 file changed, 38 insertions(+), 38 deletions(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index f637aa0706a31..5209f0ec7427d 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -163,43 +163,31 @@ static inline void iomap_dio_set_error(struct iomap_dio *dio, int ret) + cmpxchg(&dio->error, 0, ret); + } + +-void iomap_dio_bio_end_io(struct bio *bio) ++/* ++ * Called when dio->ref reaches zero from an I/O completion. ++ */ ++static void iomap_dio_done(struct iomap_dio *dio) + { +- struct iomap_dio *dio = bio->bi_private; +- bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); + struct kiocb *iocb = dio->iocb; + +- if (bio->bi_status) +- iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); +- if (!atomic_dec_and_test(&dio->ref)) +- goto release_bio; +- +- /* +- * Synchronous dio, task itself will handle any completion work +- * that needs after IO. All we need to do is wake the task. +- */ + if (dio->wait_for_completion) { ++ /* ++ * Synchronous I/O, task itself will handle any completion work ++ * that needs after IO. All we need to do is wake the task. ++ */ + struct task_struct *waiter = dio->submit.waiter; + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- goto release_bio; +- } +- +- /* +- * Flagged with IOMAP_DIO_INLINE_COMP, we can complete it inline +- */ +- if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); +- goto release_bio; +- } +- +- /* +- * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then schedule +- * our completion that way to avoid an async punt to a workqueue. +- */ +- if (dio->flags & IOMAP_DIO_CALLER_COMP) { ++ } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { ++ /* ++ * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then ++ * schedule our completion that way to avoid an async punt to a ++ * workqueue. ++ */ + /* only polled IO cares about private cleared */ + iocb->private = dio; + iocb->dio_complete = iomap_dio_deferred_complete; +@@ -217,19 +205,31 @@ void iomap_dio_bio_end_io(struct bio *bio) + * issuer. + */ + iocb->ki_complete(iocb, 0); +- goto release_bio; ++ } else { ++ struct inode *inode = file_inode(iocb->ki_filp); ++ ++ /* ++ * Async DIO completion that requires filesystem level ++ * completion work gets punted to a work queue to complete as ++ * the operation may require more IO to be issued to finalise ++ * filesystem metadata changes or guarantee data integrity. ++ */ ++ INIT_WORK(&dio->aio.work, iomap_dio_complete_work); ++ queue_work(inode->i_sb->s_dio_done_wq, &dio->aio.work); + } ++} ++ ++void iomap_dio_bio_end_io(struct bio *bio) ++{ ++ struct iomap_dio *dio = bio->bi_private; ++ bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); ++ ++ if (bio->bi_status) ++ iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); ++ ++ if (atomic_dec_and_test(&dio->ref)) ++ iomap_dio_done(dio); + +- /* +- * Async DIO completion that requires filesystem level completion work +- * gets punted to a work queue to complete as the operation may require +- * more IO to be issued to finalise filesystem metadata changes or +- * guarantee data integrity. +- */ +- INIT_WORK(&dio->aio.work, iomap_dio_complete_work); +- queue_work(file_inode(iocb->ki_filp)->i_sb->s_dio_done_wq, +- &dio->aio.work); +-release_bio: + if (should_dirty) { + bio_check_pages_dirty(bio); + } else { +-- +2.51.0 + diff --git a/queue-6.12/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-6.12/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..d9219ad135 --- /dev/null +++ b/queue-6.12/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From 43748357ef4a154ac4ead8cef335a097a917442f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 0c35a235ab6d0..1a72d067e5843 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -299,17 +299,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -332,6 +334,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-6.12/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch b/queue-6.12/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch new file mode 100644 index 0000000000..8d667d3736 --- /dev/null +++ b/queue-6.12/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch @@ -0,0 +1,46 @@ +From f6e084584d346a9b1301cc9a63c1011f46f6257e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 11:09:17 -0800 +Subject: iommu/arm-smmu-v3: Fix error check in arm_smmu_alloc_cd_tables + +From: Ryan Huang + +[ Upstream commit 5941f0e0c1e0be03ebc15b461f64208f5250d3d9 ] + +In arm_smmu_alloc_cd_tables(), the error check following the +dma_alloc_coherent() for cd_table->l2.l1tab incorrectly tests +cd_table->l2.l2ptrs. + +This means an allocation failure for l1tab goes undetected, causing +the function to return 0 (success) erroneously. + +Correct the check to test cd_table->l2.l1tab. + +Fixes: e3b1be2e73db ("iommu/arm-smmu-v3: Reorganize struct arm_smmu_ctx_desc_cfg") +Signed-off-by: Daniel Mentz +Signed-off-by: Ryan Huang +Reviewed-by: Nicolin Chen +Reviewed-by: Pranjal Shrivastava +Reviewed-by: Jason Gunthorpe +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 172ce20301971..560a670ee7911 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -1441,7 +1441,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) + cd_table->l2.l1tab = dma_alloc_coherent(smmu->dev, l1size, + &cd_table->cdtab_dma, + GFP_KERNEL); +- if (!cd_table->l2.l2ptrs) { ++ if (!cd_table->l2.l1tab) { + ret = -ENOMEM; + goto err_free_l2ptrs; + } +-- +2.51.0 + diff --git a/queue-6.12/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch b/queue-6.12/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch new file mode 100644 index 0000000000..f612c5a94a --- /dev/null +++ b/queue-6.12/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch @@ -0,0 +1,39 @@ +From 9e71c84e6f4c1c82ecbb6570ab6a195baf1344b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:16:13 +0800 +Subject: iommu/vt-d: Fix unused invalidation hint in qi_desc_iotlb + +From: Aashish Sharma + +[ Upstream commit 6b38a108eeb3936b21643191db535a35dd7c890b ] + +Invalidation hint (ih) in the function 'qi_desc_iotlb' is initialized +to zero and never used. It is embedded in the 0th bit of the 'addr' +parameter. Get the correct 'ih' value from there. + +Fixes: f701c9f36bcb ("iommu/vt-d: Factor out invalidation descriptor composition") +Signed-off-by: Aashish Sharma +Link: https://lore.kernel.org/r/20251009010903.1323979-1-aashish@aashishsharma.net +Signed-off-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/intel/iommu.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h +index df24a62e8ca40..5b5f57d694afd 100644 +--- a/drivers/iommu/intel/iommu.h ++++ b/drivers/iommu/intel/iommu.h +@@ -1088,7 +1088,7 @@ static inline void qi_desc_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, + struct qi_desc *desc) + { + u8 dw = 0, dr = 0; +- int ih = 0; ++ int ih = addr & 1; + + if (cap_write_drain(iommu->cap)) + dw = 1; +-- +2.51.0 + diff --git a/queue-6.12/ipv6-clear-ra-flags-when-adding-a-static-route.patch b/queue-6.12/ipv6-clear-ra-flags-when-adding-a-static-route.patch new file mode 100644 index 0000000000..7735d7adb0 --- /dev/null +++ b/queue-6.12/ipv6-clear-ra-flags-when-adding-a-static-route.patch @@ -0,0 +1,54 @@ +From 6db88b2d7d3603c47dfe6399726d727d0b8851b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:59:38 +0100 +Subject: ipv6: clear RA flags when adding a static route + +From: Fernando Fernandez Mancera + +[ Upstream commit f72514b3c5698e4b900b25345e09f9ed33123de6 ] + +When an IPv6 Router Advertisement (RA) is received for a prefix, the +kernel creates the corresponding on-link route with flags RTF_ADDRCONF +and RTF_PREFIX_RT configured and RTF_EXPIRES if lifetime is set. + +If later a user configures a static IPv6 address on the same prefix the +kernel clears the RTF_EXPIRES flag but it doesn't clear the RTF_ADDRCONF +and RTF_PREFIX_RT. When the next RA for that prefix is received, the +kernel sees the route as RA-learned and wrongly configures back the +lifetime. This is problematic because if the route expires, the static +address won't have the corresponding on-link route. + +This fix clears the RTF_ADDRCONF and RTF_PREFIX_RT flags preventing that +the lifetime is configured when the next RA arrives. If the static +address is deleted, the route becomes RA-learned again. + +Fixes: 14ef37b6d00e ("ipv6: fix route lookup in addrconf_prefix_rcv()") +Reported-by: Garri Djavadyan +Closes: https://lore.kernel.org/netdev/ba807d39aca5b4dcf395cc11dca61a130a52cfd3.camel@gmail.com/ +Signed-off-by: Fernando Fernandez Mancera +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20251115095939.6967-1-fmancera@suse.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index aa1046fbf28e5..ebfe2b9b11b7e 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1138,6 +1138,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_set_expires(iter, rt->expires); + fib6_add_gc_list(iter); + } ++ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { ++ iter->fib6_flags &= ~RTF_ADDRCONF; ++ iter->fib6_flags &= ~RTF_PREFIX_RT; ++ } + + if (rt->fib6_pmtu) + fib6_metric_set(iter, RTAX_MTU, +-- +2.51.0 + diff --git a/queue-6.12/irqchip-imx-mu-msi-fix-section-mismatch.patch b/queue-6.12/irqchip-imx-mu-msi-fix-section-mismatch.patch new file mode 100644 index 0000000000..5d729ae067 --- /dev/null +++ b/queue-6.12/irqchip-imx-mu-msi-fix-section-mismatch.patch @@ -0,0 +1,63 @@ +From 2932305f7c5f482bf3a10897f5dfce99534bc97e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:06 +0200 +Subject: irqchip/imx-mu-msi: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 64acfd8e680ff8992c101fe19aadb112ce551072 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index 4342a21de1eb0..b14b2e6db0b5c 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -295,9 +295,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int __init imx_mu_of_init(struct device_node *dn, +- struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { + struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; +@@ -415,20 +414,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + } + +-static int __init imx_mu_imx6sx_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + } + +-static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + } +-- +2.51.0 + diff --git a/queue-6.12/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch b/queue-6.12/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch new file mode 100644 index 0000000000..4b68c09096 --- /dev/null +++ b/queue-6.12/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch @@ -0,0 +1,50 @@ +From 26bcd8d231c63da7ab3023874b74e23d7915cbcc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:03 +0200 +Subject: irqchip/irq-bcm7038-l1: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index 36e71af054e97..bca43fa99c8f2 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -219,9 +219,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, + } + #endif + +-static int __init bcm7038_l1_init_one(struct device_node *dn, +- unsigned int idx, +- struct bcm7038_l1_chip *intc) ++static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, ++ struct bcm7038_l1_chip *intc) + { + struct resource res; + resource_size_t sz; +@@ -395,8 +394,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int __init bcm7038_l1_of_init(struct device_node *dn, +- struct device_node *parent) ++static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) + { + struct bcm7038_l1_chip *intc; + int idx, ret; +-- +2.51.0 + diff --git a/queue-6.12/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch b/queue-6.12/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..546853a296 --- /dev/null +++ b/queue-6.12/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch @@ -0,0 +1,79 @@ +From a1e738f372b0780cc0d11d24dede4fb8db316ea9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:04 +0200 +Subject: irqchip/irq-bcm7120-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bfc0c5beab1fde843677923cf008f41d583c980a ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index 1e9dab6e0d86f..bb6e56629e532 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -147,8 +147,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + int ret; + +@@ -181,8 +180,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + unsigned int gc_idx; + +@@ -212,10 +210,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_probe(struct device_node *dn, +- struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, +- struct bcm7120_l2_intc_data *), ++ struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; +@@ -343,15 +340,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, + return ret; + } + +-static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); +-- +2.51.0 + diff --git a/queue-6.12/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch b/queue-6.12/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..c149c10085 --- /dev/null +++ b/queue-6.12/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch @@ -0,0 +1,58 @@ +From dcf41fbb031beb6edd27515a42ccf49e7b39f065 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:05 +0200 +Subject: irqchip/irq-brcmstb-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bbe1775924478e95372c2f896064ab6446000713 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index c988886917f73..60863b2548f5a 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -168,10 +168,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_gc_unlock_irqrestore(gc, flags); + } + +-static int __init brcmstb_l2_intc_of_init(struct device_node *np, +- struct device_node *parent, +- const struct brcmstb_intc_init_params +- *init_params) ++static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; +@@ -287,14 +285,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, + return ret; + } + +-static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + } + +-static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + } +-- +2.51.0 + diff --git a/queue-6.12/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-6.12/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..d0563dfd52 --- /dev/null +++ b/queue-6.12/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From 43f6e710bccd1d48615f1710a9b9aea673fc3bec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-6.12/irqchip-renesas-rzg2l-fix-section-mismatch.patch b/queue-6.12/irqchip-renesas-rzg2l-fix-section-mismatch.patch new file mode 100644 index 0000000000..c32795e3ae --- /dev/null +++ b/queue-6.12/irqchip-renesas-rzg2l-fix-section-mismatch.patch @@ -0,0 +1,45 @@ +From 634f3f37ef6cdb0c90c090ca14a1ec41802fb3de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:07 +0200 +Subject: irqchip/renesas-rzg2l: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 5b338fbb2b5b21d61a9eaba14dcf43108de30258 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: d011c022efe27579 ("irqchip/renesas-rzg2l: Add support for RZ/Five SoC") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-renesas-rzg2l.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c +index 99e27e01b0b19..d83dfc10ff49e 100644 +--- a/drivers/irqchip/irq-renesas-rzg2l.c ++++ b/drivers/irqchip/irq-renesas-rzg2l.c +@@ -613,14 +613,12 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * + return ret; + } + +-static int __init rzg2l_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip); + } + +-static int __init rzfive_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzfive_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip); + } +-- +2.51.0 + diff --git a/queue-6.12/irqchip-starfive-jh8100-fix-section-mismatch.patch b/queue-6.12/irqchip-starfive-jh8100-fix-section-mismatch.patch new file mode 100644 index 0000000000..13734f07f9 --- /dev/null +++ b/queue-6.12/irqchip-starfive-jh8100-fix-section-mismatch.patch @@ -0,0 +1,38 @@ +From f7792da8b39f053f65544c3678514814c5ef5cbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:08 +0200 +Subject: irqchip/starfive-jh8100: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit f798bdb9aa81c425184f92e3d0b44d3b53d10da7 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: e4e535036173 ("irqchip: Add StarFive external interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Changhuang Liang +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-starfive-jh8100-intc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c +index 0f5837176e53f..bbe36963ccf16 100644 +--- a/drivers/irqchip/irq-starfive-jh8100-intc.c ++++ b/drivers/irqchip/irq-starfive-jh8100-intc.c +@@ -114,8 +114,7 @@ static void starfive_intc_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static int __init starfive_intc_init(struct device_node *intc, +- struct device_node *parent) ++static int starfive_intc_init(struct device_node *intc, struct device_node *parent) + { + struct starfive_irq_chip *irqc; + struct reset_control *rst; +-- +2.51.0 + diff --git a/queue-6.12/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch b/queue-6.12/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch new file mode 100644 index 0000000000..cf30170766 --- /dev/null +++ b/queue-6.12/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch @@ -0,0 +1,51 @@ +From a399529455acdad81730b0e46b291dcaa04363cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 08:13:32 -0700 +Subject: kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node + +From: Will Rosenberg + +[ Upstream commit 382b1e8f30f779af8d6d33268e53df7de579ef3c ] + +There exists a memory leak of kernfs_iattrs contained as an element +of kernfs_node allocated in __kernfs_new_node(). __kernfs_setattr() +allocates kernfs_iattrs as a sub-object, and the LSM security check +incorrectly errors out and does not free the kernfs_iattrs sub-object. + +Make an additional error out case that properly frees kernfs_iattrs if +security_kernfs_init_security() fails. + +Fixes: e19dfdc83b60 ("kernfs: initialize security of newly created nodes") +Co-developed-by: Oliver Rosenberg +Signed-off-by: Oliver Rosenberg +Signed-off-by: Will Rosenberg +Link: https://patch.msgid.link/20251125151332.2010687-1-whrosenb@asu.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/dir.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index 5dc90a498e75d..116ada5bc27c7 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -662,11 +662,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + if (parent) { + ret = security_kernfs_init_security(parent, kn); + if (ret) +- goto err_out3; ++ goto err_out4; + } + + return kn; + ++ err_out4: ++ simple_xattrs_free(&kn->iattr->xattrs, NULL); ++ kmem_cache_free(kernfs_iattrs_cache, kn->iattr); + err_out3: + spin_lock(&kernfs_idr_lock); + idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); +-- +2.51.0 + diff --git a/queue-6.12/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-6.12/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..0ec6c63fdb --- /dev/null +++ b/queue-6.12/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From d3ec6b20275da6caf7a13a53b958da21cf7ebf3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index e95287416ef87..99df46f2d9f52 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-6.12/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch b/queue-6.12/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch new file mode 100644 index 0000000000..bc1d5eb422 --- /dev/null +++ b/queue-6.12/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch @@ -0,0 +1,51 @@ +From 1496cc4294614fa21416cac3b865c25a073e9e98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:06:43 +0800 +Subject: leds: rgb: leds-qcom-lpg: Don't enable TRILED when configuring PWM + +From: Fenglin Wu + +[ Upstream commit 072cd5f458d76b9e15d89ebdaea8b5cb1312eeef ] + +The PWM signal from the LPG channel can be routed to PMIC GPIOs with +proper GPIO configuration, and it is not necessary to enable the +TRILED channel in that case. This also applies to the LPG channels +that mapped to TRILED channels. Additionally, enabling the TRILED +channel unnecessarily would cause a voltage increase in its power +supply. Hence remove it. + +Fixes: 24e2d05d1b68 ("leds: Add driver for Qualcomm LPG") +Signed-off-by: Fenglin Wu +Reviewed-by: Bjorn Andersson +Link: https://patch.msgid.link/20251119-lpg_triled_fix-v3-2-84b6dbdc774a@oss.qualcomm.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/rgb/leds-qcom-lpg.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c +index 5d8e27e2e7ae7..84e02867f3b43 100644 +--- a/drivers/leds/rgb/leds-qcom-lpg.c ++++ b/drivers/leds/rgb/leds-qcom-lpg.c +@@ -2,7 +2,7 @@ + /* + * Copyright (c) 2017-2022 Linaro Ltd + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. +- * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -1246,8 +1246,6 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + + lpg_apply(chan); + +- triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); +- + out_unlock: + mutex_unlock(&lpg->lock); + +-- +2.51.0 + diff --git a/queue-6.12/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-6.12/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..a6405f57cc --- /dev/null +++ b/queue-6.12/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From 6140c6dd747b53f0deea978f862bcdaab53108ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index a69e71a1ca55e..511c55d7b3abf 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1860,9 +1860,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1928,6 +1925,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-6.12/libbpf-fix-parsing-of-multi-split-btf.patch b/queue-6.12/libbpf-fix-parsing-of-multi-split-btf.patch new file mode 100644 index 0000000000..5fde9b371d --- /dev/null +++ b/queue-6.12/libbpf-fix-parsing-of-multi-split-btf.patch @@ -0,0 +1,51 @@ +From a7643f998805bd3a6432607469adcc7e4f4dbcf1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:33:08 +0000 +Subject: libbpf: Fix parsing of multi-split BTF + +From: Alan Maguire + +[ Upstream commit 4f596acc260e691a2e348f64230392f3472feea3 ] + +When creating multi-split BTF we correctly set the start string offset +to be the size of the base string section plus the base BTF start +string offset; the latter is needed for multi-split BTF since the +offset is non-zero there. + +Unfortunately the BTF parsing case needed that logic and it was +missed. + +Fixes: 4e29128a9ace ("libbpf/btf: Fix string handling to support multi-split BTF") +Signed-off-by: Alan Maguire +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20251104203309.318429-2-alan.maguire@oracle.com +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/btf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c +index b770702dab372..56935f86a6963 100644 +--- a/tools/lib/bpf/btf.c ++++ b/tools/lib/bpf/btf.c +@@ -1046,7 +1046,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf) + if (base_btf) { + btf->base_btf = base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + btf->raw_data = malloc(size); +@@ -5504,7 +5504,7 @@ void btf_set_base_btf(struct btf *btf, const struct btf *base_btf) + { + btf->base_btf = (struct btf *)base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + int btf__relocate(struct btf *btf, const struct btf *base_btf) +-- +2.51.0 + diff --git a/queue-6.12/locktorture-fix-memory-leak-in-param_set_cpumask.patch b/queue-6.12/locktorture-fix-memory-leak-in-param_set_cpumask.patch new file mode 100644 index 0000000000..1d7b65b8aa --- /dev/null +++ b/queue-6.12/locktorture-fix-memory-leak-in-param_set_cpumask.patch @@ -0,0 +1,84 @@ +From 4a7a5eeece9d885b49eb8078b9ede92be6765669 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 12:19:56 -0800 +Subject: locktorture: Fix memory leak in param_set_cpumask() + +From: Wang Liang + +[ Upstream commit e52b43883d084a9af263c573f2a1bd1ca5088389 ] + +With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via +alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when +setting the module parameter multiple times by sysfs interface or removing +module. + +Below kmemleak trace is seen for this issue: + +unreferenced object 0xffff888100aabff8 (size 8): + comm "bash", pid 323, jiffies 4295059233 + hex dump (first 8 bytes): + 07 00 00 00 00 00 00 00 ........ + backtrace (crc ac50919): + __kmalloc_node_noprof+0x2e5/0x420 + alloc_cpumask_var_node+0x1f/0x30 + param_set_cpumask+0x26/0xb0 [locktorture] + param_attr_store+0x93/0x100 + module_attr_store+0x1b/0x30 + kernfs_fop_write_iter+0x114/0x1b0 + vfs_write+0x300/0x410 + ksys_write+0x60/0xd0 + do_syscall_64+0xa4/0x260 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +This issue can be reproduced by: + insmod locktorture.ko bind_writers=1 + rmmod locktorture + +or: + insmod locktorture.ko bind_writers=1 + echo 2 > /sys/module/locktorture/parameters/bind_writers + +Considering that setting the module parameter 'bind_writers' or +'bind_readers' by sysfs interface has no real effect, set the parameter +permissions to 0444. To fix the memory leak when removing module, free +'bind_writers' and 'bind_readers' memory in lock_torture_cleanup(). + +Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters") +Suggested-by: Zhang Changzhong +Signed-off-by: Wang Liang +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/locking/locktorture.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c +index de95ec07e4771..4a7fa0b74d52d 100644 +--- a/kernel/locking/locktorture.c ++++ b/kernel/locking/locktorture.c +@@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = { + .get = param_get_cpumask, + }; + +-module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0644); +-module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0644); ++module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0444); ++module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0444); + + long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask); + +@@ -1157,6 +1157,10 @@ static void lock_torture_cleanup(void) + cxt.cur_ops->exit(); + cxt.init_called = false; + } ++ ++ free_cpumask_var(bind_readers); ++ free_cpumask_var(bind_writers); ++ + torture_cleanup_end(); + } + +-- +2.51.0 + diff --git a/queue-6.12/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-6.12/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..f47893a770 --- /dev/null +++ b/queue-6.12/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From f8360bea5eab4f8af53019022209b57e6f129a44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index b461b1bed25b2..6247dbe493dea 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -187,13 +187,14 @@ static int mac_hid_toggle_emumouse(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-6.12/md-fix-rcu-protection-in-md_wakeup_thread.patch b/queue-6.12/md-fix-rcu-protection-in-md_wakeup_thread.patch new file mode 100644 index 0000000000..da2cf18a46 --- /dev/null +++ b/queue-6.12/md-fix-rcu-protection-in-md_wakeup_thread.patch @@ -0,0 +1,114 @@ +From 2b523a46d93de380fe1dbb5c500b968064caeade Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:32:27 +0800 +Subject: md: fix rcu protection in md_wakeup_thread + +From: Yun Zhou + +[ Upstream commit 0dc76205549b4c25705e54345f211b9f66e018a0 ] + +We attempted to use RCU to protect the pointer 'thread', but directly +passed the value when calling md_wakeup_thread(). This means that the +RCU pointer has been acquired before rcu_read_lock(), which renders +rcu_read_lock() ineffective and could lead to a use-after-free. + +Link: https://lore.kernel.org/linux-raid/20251015083227.1079009-1-yun.zhou@windriver.com +Fixes: 446931543982 ("md: protect md_thread with rcu") +Signed-off-by: Yun Zhou +Reviewed-by: Li Nan +Reviewed-by: Yu Kuai +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 14 ++++++-------- + drivers/md/md.h | 8 +++++++- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index d263076442924..5c39246c467e3 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -106,7 +106,7 @@ static int remove_and_add_spares(struct mddev *mddev, + struct md_rdev *this); + static void mddev_detach(struct mddev *mddev); + static void export_rdev(struct md_rdev *rdev, struct mddev *mddev); +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread); ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread); + + /* + * Default number of read corrections we'll attempt on an rdev +@@ -4899,7 +4899,7 @@ static void stop_sync_thread(struct mddev *mddev, bool locked) + * Thread might be blocked waiting for metadata update which will now + * never happen + */ +- md_wakeup_thread_directly(mddev->sync_thread); ++ md_wakeup_thread_directly(&mddev->sync_thread); + if (work_pending(&mddev->sync_work)) + flush_work(&mddev->sync_work); + +@@ -8051,22 +8051,21 @@ static int md_thread(void *arg) + return 0; + } + +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread) ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread) + { + struct md_thread *t; + + rcu_read_lock(); +- t = rcu_dereference(thread); ++ t = rcu_dereference(*thread); + if (t) + wake_up_process(t->tsk); + rcu_read_unlock(); + } + +-void md_wakeup_thread(struct md_thread __rcu *thread) ++void __md_wakeup_thread(struct md_thread __rcu *thread) + { + struct md_thread *t; + +- rcu_read_lock(); + t = rcu_dereference(thread); + if (t) { + pr_debug("md: waking up MD thread %s.\n", t->tsk->comm); +@@ -8074,9 +8073,8 @@ void md_wakeup_thread(struct md_thread __rcu *thread) + if (wq_has_sleeper(&t->wqueue)) + wake_up(&t->wqueue); + } +- rcu_read_unlock(); + } +-EXPORT_SYMBOL(md_wakeup_thread); ++EXPORT_SYMBOL(__md_wakeup_thread); + + struct md_thread *md_register_thread(void (*run) (struct md_thread *), + struct mddev *mddev, const char *name) +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 8826dce9717da..20857b8984625 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -838,6 +838,12 @@ struct md_io_clone { + + #define THREAD_WAKEUP 0 + ++#define md_wakeup_thread(thread) do { \ ++ rcu_read_lock(); \ ++ __md_wakeup_thread(thread); \ ++ rcu_read_unlock(); \ ++} while (0) ++ + static inline void safe_put_page(struct page *p) + { + if (p) put_page(p); +@@ -855,7 +861,7 @@ extern struct md_thread *md_register_thread( + struct mddev *mddev, + const char *name); + extern void md_unregister_thread(struct mddev *mddev, struct md_thread __rcu **threadp); +-extern void md_wakeup_thread(struct md_thread __rcu *thread); ++extern void __md_wakeup_thread(struct md_thread __rcu *thread); + extern void md_check_recovery(struct mddev *mddev); + extern void md_reap_sync_thread(struct mddev *mddev); + extern enum sync_action md_sync_action(struct mddev *mddev); +-- +2.51.0 + diff --git a/queue-6.12/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch b/queue-6.12/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch new file mode 100644 index 0000000000..fd8ecb7580 --- /dev/null +++ b/queue-6.12/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch @@ -0,0 +1,99 @@ +From 6e5b29b4828f5a3d0361b5bac7eb449abbe21e0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 16:55:57 +0800 +Subject: md/raid5: fix IO hang when array is broken with IO inflight + +From: Yu Kuai + +[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ] + +Following test can cause IO hang: + +mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none +sleep 5 +echo 1 > /sys/block/sda/device/delete +echo 1 > /sys/block/sdb/device/delete +echo 1 > /sys/block/sdc/device/delete +echo 1 > /sys/block/sdd/device/delete + +dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct + +Root cause: + +1) all disks removed, however all rdevs in the array is still in sync, +IO will be issued normally. + +2) IO failure from sda, and set badblocks failed, sda will be faulty +and MD_SB_CHANGING_PENDING will be set. + +3) error recovery try to recover this IO from other disks, IO will be +issued to sdb, sdc, and sdd. + +4) IO failure from sdb, and set badblocks failed again, now array is +broken and will become read-only. + +5) IO failure from sdc and sdd, however, stripe can't be handled anymore +because MD_SB_CHANGING_PENDING is set: + +handle_stripe + handle_stripe + if (test_bit MD_SB_CHANGING_PENDING) + set_bit STRIPE_HANDLE + goto finish + // skip handling failed stripe + +release_stripe + if (test_bit STRIPE_HANDLE) + list_add_tail conf->hand_list + +6) later raid5d can't handle failed stripe as well: + +raid5d + md_check_recovery + md_update_sb + if (!md_is_rdwr()) + // can't clear pending bit + return + if (test_bit MD_SB_CHANGING_PENDING) + break; + // can't handle failed stripe + +Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, +fix this problem by skip this checking for read-only array. + +Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com +Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") +Signed-off-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 4fae8ade24090..8e5ccca3b68b8 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -4947,7 +4947,8 @@ static void handle_stripe(struct stripe_head *sh) + goto finish; + + if (s.handle_bad_blocks || +- test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { ++ (md_is_rdwr(conf->mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { + set_bit(STRIPE_HANDLE, &sh->state); + goto finish; + } +@@ -6763,7 +6764,8 @@ static void raid5d(struct md_thread *thread) + int batch_size, released; + unsigned int offset; + +- if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ if (md_is_rdwr(mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + + released = release_stripe_list(conf, conf->temp_inactive_list); +-- +2.51.0 + diff --git a/queue-6.12/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-6.12/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..83b80a6101 --- /dev/null +++ b/queue-6.12/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From f672bb18499eef95da4f8a9c4d4abbd2f24c996c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index 1f727ef60d638..8c989b74f924e 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.12/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..7c65f652ea --- /dev/null +++ b/queue-6.12/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From aa76ca5dedef97499aad0c223ee16a5b7660902c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index 49830b526ee88..10a0952615a17 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -286,6 +286,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.12/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..4d52bc94f3 --- /dev/null +++ b/queue-6.12/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 1ef650de596b8c3108884abd4d11dbd5f9ba50a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 886745b5b607c..1e83f7c7ce145 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -208,6 +208,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-6.12/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..4843956ea1 --- /dev/null +++ b/queue-6.12/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From fdfb3ca4fa0571053791ec5d10dbd6f7d4146b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 1cc8fc8fefe74..40e15a0ba95a9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -874,8 +874,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-6.12/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-6.12/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..3e5f7ad2fc --- /dev/null +++ b/queue-6.12/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From 216a1a22524245c00a8cc576d620ba888b480df3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index 14e36ae71958f..bd76479b90e4a 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-6.12/mtd-nand-relax-ecc-parameter-validation-check.patch b/queue-6.12/mtd-nand-relax-ecc-parameter-validation-check.patch new file mode 100644 index 0000000000..4628cf5312 --- /dev/null +++ b/queue-6.12/mtd-nand-relax-ecc-parameter-validation-check.patch @@ -0,0 +1,53 @@ +From ff2c820512a4c92a4bf8cbafcfcd2fba942c120e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:42 +1300 +Subject: mtd: nand: relax ECC parameter validation check + +From: Aryan Srivastava + +[ Upstream commit 050553c683f21eebd7d1020df9b2ec852e2a9e4e ] + +Due to the custom handling and layouts of certain nand controllers this +validity check will always fail for certain layouts. The check +inherently depends on even chunk sizing and this is not always the +case. + +Modify the check to only print a warning, instead of failing to +init the attached NAND. This allows various 8 bit and 12 ECC strength +layouts to be used. + +Fixes: 68c18dae6888 ("mtd: rawnand: marvell: add missing layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/nand_base.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index 53e16d39af4bf..3e1844bfb8089 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -6469,11 +6469,14 @@ static int nand_scan_tail(struct nand_chip *chip) + ecc->steps = mtd->writesize / ecc->size; + if (!base->ecc.ctx.nsteps) + base->ecc.ctx.nsteps = ecc->steps; +- if (ecc->steps * ecc->size != mtd->writesize) { +- WARN(1, "Invalid ECC parameters\n"); +- ret = -EINVAL; +- goto err_nand_manuf_cleanup; +- } ++ ++ /* ++ * Validity check: Warn if ECC parameters are not compatible with page size. ++ * Due to the custom handling of ECC blocks in certain controllers the check ++ * may result in an expected failure. ++ */ ++ if (ecc->steps * ecc->size != mtd->writesize) ++ pr_warn("ECC parameters may be invalid in reference to underlying NAND chip\n"); + + if (!ecc->total) { + ecc->total = ecc->steps * ecc->bytes; +-- +2.51.0 + diff --git a/queue-6.12/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch b/queue-6.12/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch new file mode 100644 index 0000000000..28b29cb47d --- /dev/null +++ b/queue-6.12/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch @@ -0,0 +1,50 @@ +From 89368229944b784a1ceb37d8888c8f9fd516f1d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 17:47:47 +0800 +Subject: mtd: rawnand: lpc32xx_slc: fix GPIO descriptor leak on probe error + and remove + +From: Haotian Zhang + +[ Upstream commit cdf44f1add4ec9ee80569d5a43e6e9bba0d74c7a ] + +The driver calls gpiod_get_optional() in the probe function but +never calls gpiod_put() in the remove function or in the probe +error path. This leads to a GPIO descriptor resource leak. +The lpc32xx_mlc.c driver in the same directory handles this +correctly by calling gpiod_put() on both paths. + +Add gpiod_put() in the remove function and in the probe error path +to fix the resource leak. + +Fixes: 6b923db2867c ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") +Signed-off-by: Haotian Zhang +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/lpc32xx_slc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c +index ade971e4cc3b2..09d6c4f90d85a 100644 +--- a/drivers/mtd/nand/raw/lpc32xx_slc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c +@@ -937,6 +937,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) + dma_release_channel(host->dma_chan); + enable_wp: + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + + return res; + } +@@ -962,6 +963,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev) + writel(tmp, SLC_CTRL(host->io_base)); + + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + } + + static int lpc32xx_nand_resume(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.12/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch b/queue-6.12/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch new file mode 100644 index 0000000000..4a5adcb516 --- /dev/null +++ b/queue-6.12/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch @@ -0,0 +1,45 @@ +From 2862046a1d2088a7155de9ba157cb8d464a7b212 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 00:35:51 +0800 +Subject: mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors + +From: Haotian Zhang + +[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ] + +devm_pm_runtime_enable() can fail due to memory allocation failures. +The current code ignores its return value and proceeds with +pm_runtime_resume_and_get(), which may operate on incorrectly +initialized runtime PM state. + +Check the return value of devm_pm_runtime_enable() and return the +error code if it fails. + +Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c +index ed45d0add3e96..efb19cc298ade 100644 +--- a/drivers/mtd/nand/raw/renesas-nand-controller.c ++++ b/drivers/mtd/nand/raw/renesas-nand-controller.c +@@ -1336,7 +1336,10 @@ static int rnandc_probe(struct platform_device *pdev) + if (IS_ERR(rnandc->regs)) + return PTR_ERR(rnandc->regs); + +- devm_pm_runtime_enable(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +-- +2.51.0 + diff --git a/queue-6.12/nbd-defer-config-put-in-recv_work.patch b/queue-6.12/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..3cfb3ed345 --- /dev/null +++ b/queue-6.12/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From 4a06fd544f59a16fc1ea7d1efbf5914ac9602efe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index deb298371a6a3..e6b756c475cde 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -963,9 +963,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-6.12/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-6.12/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..bcbb3a828d --- /dev/null +++ b/queue-6.12/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From b42ab708a90765fcb4ac3887d89cd4ae61e5ea88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index e6b756c475cde..958bd115a3417 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2169,12 +2169,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-6.12/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch b/queue-6.12/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch new file mode 100644 index 0000000000..12ab903fce --- /dev/null +++ b/queue-6.12/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch @@ -0,0 +1,83 @@ +From 45cbec871603b9119574e7b189132f0731946308 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:46 +0200 +Subject: net: dsa: xrs700x: reject unsupported HSR configurations + +From: Vladimir Oltean + +[ Upstream commit 30296ac7642652428396222e720718f2661e9425 ] + +As discussed here: +https://lore.kernel.org/netdev/20240620090210.drop6jwh7e5qw556@skbuf/ + +the fact is that the xrs700x.c driver only supports offloading +HSR_PT_SLAVE_A and HSR_PT_SLAVE_B (which were the only port types at the +time the offload was written, _for this driver_). + +Up until now, the API did not explicitly tell offloading drivers what +port has what role. So xrs700x can get confused and think that it can +support a configuration which it actually can't. There was a table in +the attached link which gave an example: + +$ ip link add name hsr0 type hsr slave1 swp0 slave2 swp1 \ + interlink swp2 supervision 45 version 1 + + HSR_PT_SLAVE_A HSR_PT_SLAVE_B HSR_PT_INTERLINK + ---------------------------------------------------------------- + user + space 0 1 2 + requests + ---------------------------------------------------------------- + XRS700X + driver 1 2 - + understands + +The switch would act as if the ring ports were swp1 and swp2. + +Now that we have explicit hsr_get_port_type() API, let's use that to +work around the unintended semantical changes of the offloading API +brought by the introduction of interlink ports in HSR. + +Fixes: 5055cccfc2d1 ("net: hsr: Provide RedBox support (HSR-SAN)") +Cc: Lukasz Majewski +Signed-off-by: Vladimir Oltean +Reviewed-by: George McCollister +Link: https://patch.msgid.link/20251130131657.65080-5-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/xrs700x/xrs700x.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c +index de3b768f2ff9c..7e9a2ba6bfd95 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x.c ++++ b/drivers/net/dsa/xrs700x/xrs700x.c +@@ -568,6 +568,7 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + struct xrs700x *priv = ds->priv; + struct net_device *user; + int ret, i, hsr_pair[2]; ++ enum hsr_port_type type; + enum hsr_version ver; + bool fwd = false; + +@@ -591,6 +592,16 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + return -EOPNOTSUPP; + } + ++ ret = hsr_get_port_type(hsr, dsa_to_port(ds, port)->user, &type); ++ if (ret) ++ return ret; ++ ++ if (type != HSR_PT_SLAVE_A && type != HSR_PT_SLAVE_B) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Only HSR slave ports can be offloaded"); ++ return -EOPNOTSUPP; ++ } ++ + dsa_hsr_foreach_port(dp, ds, hsr) { + if (dp->index != port) { + partner = dp; +-- +2.51.0 + diff --git a/queue-6.12/net-hsr-create-an-api-to-get-hsr-port-type.patch b/queue-6.12/net-hsr-create-an-api-to-get-hsr-port-type.patch new file mode 100644 index 0000000000..cb99fdba69 --- /dev/null +++ b/queue-6.12/net-hsr-create-an-api-to-get-hsr-port-type.patch @@ -0,0 +1,135 @@ +From a15063352ab0a7e0b994528f8016eac2e82f5372 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:44 +0200 +Subject: net: hsr: create an API to get hsr port type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiaoliang Yang + +[ Upstream commit a0244e76213980f3b9bb5d40b0b6705fcf24230d ] + +Since the introduction of HSR_PT_INTERLINK in commit 5055cccfc2d1 ("net: +hsr: Provide RedBox support (HSR-SAN)"), we see that different port +types require different settings for hardware offload, which was not the +case before when we only had HSR_PT_SLAVE_A and HSR_PT_SLAVE_B. But +there is currently no way to know which port is which type, so create +the hsr_get_port_type() API function and export it. + +When hsr_get_port_type() is called from the device driver, the port can +must be found in the HSR port list. An important use case is for this +function to work from offloading drivers' NETDEV_CHANGEUPPER handler, +which is triggered by hsr_portdev_setup() -> netdev_master_upper_dev_link(). +Therefore, we need to move the addition of the hsr_port to the HSR port +list prior to calling hsr_portdev_setup(). This makes the error +restoration path also more similar to hsr_del_port(), where +kfree_rcu(port) is already used. + +Cc: Sebastian Andrzej Siewior +Cc: Lukasz Majewski +Signed-off-by: Xiaoliang Yang +Signed-off-by: Vladimir Oltean +Reviewed-by: Łukasz Majewski +Link: https://patch.msgid.link/20251130131657.65080-3-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + include/linux/if_hsr.h | 9 +++++++++ + net/hsr/hsr_device.c | 20 ++++++++++++++++++++ + net/hsr/hsr_slave.c | 7 ++++--- + 3 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/include/linux/if_hsr.h b/include/linux/if_hsr.h +index d7941fd880329..f4cf2dd36d193 100644 +--- a/include/linux/if_hsr.h ++++ b/include/linux/if_hsr.h +@@ -43,6 +43,8 @@ extern bool is_hsr_master(struct net_device *dev); + extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver); + struct net_device *hsr_get_port_ndev(struct net_device *ndev, + enum hsr_port_type pt); ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type); + #else + static inline bool is_hsr_master(struct net_device *dev) + { +@@ -59,6 +61,13 @@ static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev, + { + return ERR_PTR(-EINVAL); + } ++ ++static inline int hsr_get_port_type(struct net_device *hsr_dev, ++ struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ return -EINVAL; ++} + #endif /* CONFIG_HSR */ + + #endif /*_LINUX_IF_HSR_H_*/ +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index c568d91764235..386aba50930a3 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -689,6 +689,26 @@ struct net_device *hsr_get_port_ndev(struct net_device *ndev, + } + EXPORT_SYMBOL(hsr_get_port_ndev); + ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ struct hsr_priv *hsr = netdev_priv(hsr_dev); ++ struct hsr_port *port; ++ ++ rcu_read_lock(); ++ hsr_for_each_port(hsr, port) { ++ if (port->dev == dev) { ++ *type = port->type; ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return -EINVAL; ++} ++EXPORT_SYMBOL(hsr_get_port_type); ++ + /* Default multicast address for HSR Supervision frames */ + static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = { + 0x01, 0x15, 0x4e, 0x00, 0x01, 0x00 +diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c +index 9ac7cf0835118..70472726c6049 100644 +--- a/net/hsr/hsr_slave.c ++++ b/net/hsr/hsr_slave.c +@@ -203,14 +203,14 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + port->dev = dev; + port->type = type; + ++ list_add_tail_rcu(&port->port_list, &hsr->ports); ++ + if (type != HSR_PT_MASTER) { + res = hsr_portdev_setup(hsr, dev, port, extack); + if (res) + goto fail_dev_setup; + } + +- list_add_tail_rcu(&port->port_list, &hsr->ports); +- + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + netdev_update_features(master->dev); + dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); +@@ -218,7 +218,8 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + return 0; + + fail_dev_setup: +- kfree(port); ++ list_del_rcu(&port->port_list); ++ kfree_rcu(port, rcu); + return res; + } + +-- +2.51.0 + diff --git a/queue-6.12/net-hsr-create-and-export-hsr_get_port_ndev.patch b/queue-6.12/net-hsr-create-and-export-hsr_get_port_ndev.patch new file mode 100644 index 0000000000..c10706b15c --- /dev/null +++ b/queue-6.12/net-hsr-create-and-export-hsr_get_port_ndev.patch @@ -0,0 +1,120 @@ +From 2ffbb0cf290d7324585483511afb29960aa53e78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Jan 2025 13:58:51 +0530 +Subject: net: hsr: Create and export hsr_get_port_ndev() + +From: MD Danish Anwar + +[ Upstream commit 9c10dd8eed74de9e8adeb820939f8745cd566d4a ] + +Create an API to get the net_device to the slave port of HSR device. The +API will take hsr net_device and enum hsr_port_type for which we want the +net_device as arguments. + +This API can be used by client drivers who support HSR and want to get +the net_devcie of slave ports from the hsr device. Export this API for +the same. + +This API needs the enum hsr_port_type to be accessible by the drivers using +hsr. Move the enum hsr_port_type from net/hsr/hsr_main.h to +include/linux/if_hsr.h for the same. + +Signed-off-by: MD Danish Anwar +Signed-off-by: Paolo Abeni +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + include/linux/if_hsr.h | 17 +++++++++++++++++ + net/hsr/hsr_device.c | 13 +++++++++++++ + net/hsr/hsr_main.h | 9 --------- + 3 files changed, 30 insertions(+), 9 deletions(-) + +diff --git a/include/linux/if_hsr.h b/include/linux/if_hsr.h +index 0404f5bf4f30f..d7941fd880329 100644 +--- a/include/linux/if_hsr.h ++++ b/include/linux/if_hsr.h +@@ -13,6 +13,15 @@ enum hsr_version { + PRP_V1, + }; + ++enum hsr_port_type { ++ HSR_PT_NONE = 0, /* Must be 0, used by framereg */ ++ HSR_PT_SLAVE_A, ++ HSR_PT_SLAVE_B, ++ HSR_PT_INTERLINK, ++ HSR_PT_MASTER, ++ HSR_PT_PORTS, /* This must be the last item in the enum */ ++}; ++ + /* HSR Tag. + * As defined in IEC-62439-3:2010, the HSR tag is really { ethertype = 0x88FB, + * path, LSDU_size, sequence Nr }. But we let eth_header() create { h_dest, +@@ -32,6 +41,8 @@ struct hsr_tag { + #if IS_ENABLED(CONFIG_HSR) + extern bool is_hsr_master(struct net_device *dev); + extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver); ++struct net_device *hsr_get_port_ndev(struct net_device *ndev, ++ enum hsr_port_type pt); + #else + static inline bool is_hsr_master(struct net_device *dev) + { +@@ -42,6 +53,12 @@ static inline int hsr_get_version(struct net_device *dev, + { + return -EINVAL; + } ++ ++static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev, ++ enum hsr_port_type pt) ++{ ++ return ERR_PTR(-EINVAL); ++} + #endif /* CONFIG_HSR */ + + #endif /*_LINUX_IF_HSR_H_*/ +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index ae368cdcbd936..c568d91764235 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -676,6 +676,19 @@ bool is_hsr_master(struct net_device *dev) + } + EXPORT_SYMBOL(is_hsr_master); + ++struct net_device *hsr_get_port_ndev(struct net_device *ndev, ++ enum hsr_port_type pt) ++{ ++ struct hsr_priv *hsr = netdev_priv(ndev); ++ struct hsr_port *port; ++ ++ hsr_for_each_port(hsr, port) ++ if (port->type == pt) ++ return port->dev; ++ return NULL; ++} ++EXPORT_SYMBOL(hsr_get_port_ndev); ++ + /* Default multicast address for HSR Supervision frames */ + static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = { + 0x01, 0x15, 0x4e, 0x00, 0x01, 0x00 +diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h +index 37beb40763dba..677371bc36ea7 100644 +--- a/net/hsr/hsr_main.h ++++ b/net/hsr/hsr_main.h +@@ -121,15 +121,6 @@ struct hsrv1_ethhdr_sp { + struct hsr_sup_tag hsr_sup; + } __packed; + +-enum hsr_port_type { +- HSR_PT_NONE = 0, /* Must be 0, used by framereg */ +- HSR_PT_SLAVE_A, +- HSR_PT_SLAVE_B, +- HSR_PT_INTERLINK, +- HSR_PT_MASTER, +- HSR_PT_PORTS, /* This must be the last item in the enum */ +-}; +- + /* PRP Redunancy Control Trailor (RCT). + * As defined in IEC-62439-4:2012, the PRP RCT is really { sequence Nr, + * Lan indentifier (LanId), LSDU_size and PRP_suffix = 0x88FB }. +-- +2.51.0 + diff --git a/queue-6.12/net-hsr-remove-one-synchronize_rcu-from-hsr_del_port.patch b/queue-6.12/net-hsr-remove-one-synchronize_rcu-from-hsr_del_port.patch new file mode 100644 index 0000000000..ac9908d767 --- /dev/null +++ b/queue-6.12/net-hsr-remove-one-synchronize_rcu-from-hsr_del_port.patch @@ -0,0 +1,52 @@ +From fc0a2931530e4ba00862b0fcd448e6cc2b82d98f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Jan 2025 10:11:48 +0000 +Subject: net: hsr: remove one synchronize_rcu() from hsr_del_port() + +From: Eric Dumazet + +[ Upstream commit 4475d56145f368d065b05da3a5599d5620ca9408 ] + +Use kfree_rcu() instead of synchronize_rcu()+kfree(). + +This might allow syzbot to fuzz HSR a bit faster... + +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250103101148.3594545-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_main.h | 1 + + net/hsr/hsr_slave.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +diff --git a/net/hsr/hsr_main.h b/net/hsr/hsr_main.h +index f066c9c401c60..37beb40763dba 100644 +--- a/net/hsr/hsr_main.h ++++ b/net/hsr/hsr_main.h +@@ -163,6 +163,7 @@ struct hsr_port { + struct net_device *dev; + struct hsr_priv *hsr; + enum hsr_port_type type; ++ struct rcu_head rcu; + }; + + struct hsr_frame_info; +diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c +index b17909ef6632f..01762525c9456 100644 +--- a/net/hsr/hsr_slave.c ++++ b/net/hsr/hsr_slave.c +@@ -241,7 +241,5 @@ void hsr_del_port(struct hsr_port *port) + netdev_upper_dev_unlink(port->dev, master->dev); + } + +- synchronize_rcu(); +- +- kfree(port); ++ kfree_rcu(port, rcu); + } +-- +2.51.0 + diff --git a/queue-6.12/net-hsr-remove-synchronize_rcu-from-hsr_add_port.patch b/queue-6.12/net-hsr-remove-synchronize_rcu-from-hsr_add_port.patch new file mode 100644 index 0000000000..3164523c3b --- /dev/null +++ b/queue-6.12/net-hsr-remove-synchronize_rcu-from-hsr_add_port.patch @@ -0,0 +1,41 @@ +From 6d980f403f9033c670fd90d73b9e2b37c4b65bea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Jan 2025 14:47:01 +0000 +Subject: net: hsr: remove synchronize_rcu() from hsr_add_port() + +From: Eric Dumazet + +[ Upstream commit a3b3d2dc389568a77d0e25da17203e3616218e93 ] + +A synchronize_rcu() was added by mistake in commit +c5a759117210 ("net/hsr: Use list_head (and rcu) instead +of array for slave devices.") + +RCU does not mandate to observe a grace period after +list_add_tail_rcu(). + +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20250107144701.503884-1-edumazet@google.com +Signed-off-by: Paolo Abeni +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + net/hsr/hsr_slave.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c +index 01762525c9456..9ac7cf0835118 100644 +--- a/net/hsr/hsr_slave.c ++++ b/net/hsr/hsr_slave.c +@@ -210,7 +210,6 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + } + + list_add_tail_rcu(&port->port_list, &hsr->ports); +- synchronize_rcu(); + + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + netdev_update_features(master->dev); +-- +2.51.0 + diff --git a/queue-6.12/net-phy-adin1100-fix-software-power-down-ready-condi.patch b/queue-6.12/net-phy-adin1100-fix-software-power-down-ready-condi.patch new file mode 100644 index 0000000000..5c35ca4ffa --- /dev/null +++ b/queue-6.12/net-phy-adin1100-fix-software-power-down-ready-condi.patch @@ -0,0 +1,54 @@ +From 7add6bbd6bd0467b05206a9fad7f8197ad1e5dd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:47:36 +0100 +Subject: net: phy: adin1100: Fix software power-down ready condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ] + +Value CRSM_SFT_PD written to Software Power-Down Control Register +(CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value +CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for +confirmation powerdown has been reached. + +The condition could have only worked when disabling powerdown +(both 0x00), but never when enabling it (0x01 != 0x02). + +Result is a timeout, like so: + + $ ifdown eth0 + macb f802c000.ethernet eth0: Link is Down + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + +Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") +Signed-off-by: Alexander Dahl +Reviewed-by: Russell King (Oracle) +Acked-by: Nuno Sá +Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/adin1100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c +index 85f910e2d4fb2..918bb1cf7a4e7 100644 +--- a/drivers/net/phy/adin1100.c ++++ b/drivers/net/phy/adin1100.c +@@ -201,7 +201,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) + return ret; + + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, +- (ret & ADIN_CRSM_SFT_PD_RDY) == val, ++ !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, + 1000, 30000, true); + } + +-- +2.51.0 + diff --git a/queue-6.12/net-phy-aquantia-check-for-nvmem-deferral.patch b/queue-6.12/net-phy-aquantia-check-for-nvmem-deferral.patch new file mode 100644 index 0000000000..16408bb755 --- /dev/null +++ b/queue-6.12/net-phy-aquantia-check-for-nvmem-deferral.patch @@ -0,0 +1,41 @@ +From 4f30a99b650ed771e134d703c1dbf6985d449d0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 12:44:35 +0100 +Subject: net: phy: aquantia: check for NVMEM deferral + +From: Robert Marko + +[ Upstream commit a6c121a2432eee2c4ebceb1483ccd4a50a52983d ] + +Currently, if NVMEM provider is probed later than Aquantia, loading the +firmware will fail with -EINVAL. + +To fix this, simply check for -EPROBE_DEFER when NVMEM is attempted and +return it. + +Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support") +Signed-off-by: Robert Marko +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251127114514.460924-1-robimarko@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/aquantia/aquantia_firmware.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c +index dab3af80593f5..33b8c7676fb36 100644 +--- a/drivers/net/phy/aquantia/aquantia_firmware.c ++++ b/drivers/net/phy/aquantia/aquantia_firmware.c +@@ -368,7 +368,7 @@ int aqr_firmware_load(struct phy_device *phydev) + * assume that, and load a new image. + */ + ret = aqr_firmware_load_nvmem(phydev); +- if (!ret) ++ if (ret == -EPROBE_DEFER || !ret) + return ret; + + ret = aqr_firmware_load_fs(phydev); +-- +2.51.0 + diff --git a/queue-6.12/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-6.12/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..55da5a0d8d --- /dev/null +++ b/queue-6.12/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From a018e4a37310be3587b141997db0a10128e2159f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 6cbe8a7a0e5cc..8024b6503cd9a 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1592,7 +1592,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1738,14 +1737,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1818,6 +1817,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1828,13 +1829,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1843,11 +1844,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1922,24 +1923,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-6.12/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-6.12/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..00c4ba0921 --- /dev/null +++ b/queue-6.12/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From 1d6e472e73b6318f674f9fba990bbaaaec43336d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 04bacb04770fa..ce35a6f126793 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5268,10 +5268,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-6.12/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-6.12/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..bde0ddcb42 --- /dev/null +++ b/queue-6.12/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From 320cec937b5cc4571d3967d0eb2927f6793346ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index da9ebd00b1989..55734156166d2 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -141,12 +141,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-6.12/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-6.12/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..2ccdd4b578 --- /dev/null +++ b/queue-6.12/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,503 @@ +From 690f29c34ec64591698cf9abce4412f6aba552cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index 1b58b5b91ff6a..52a06de41aa0f 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -18,15 +18,14 @@ struct nf_conncount_list { + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen); + void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 913ede2f57f9a..0ffc5ff78a714 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if ((u32)jiffies == list->last_gc) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen) + { +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 92b984fa8175c..d998e27713ac7 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index 0189f8b6b0bd1..848287ab79cfb 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index e573e92213029..a0811e1fba656 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -928,8 +928,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -942,8 +942,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -972,8 +973,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -1770,8 +1770,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-6.12/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-6.12/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..359ca634e5 --- /dev/null +++ b/queue-6.12/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From 327e51482735008d0593ba1f507b39dc37673dbf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 0ffc5ff78a714..b84cfb5616df4 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if ((u32)jiffies == list->last_gc) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index d998e27713ac7..83a7d5769396c 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-6.12/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-6.12/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..cf6759975d --- /dev/null +++ b/queue-6.12/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 8c2330465288056fdbdfc316b574705c162e796c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index 0822d8a119c6f..eefe50a17c4a0 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -53,7 +54,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-6.12/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-6.12/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..b5d1ddea47 --- /dev/null +++ b/queue-6.12/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From 8e32f0bfb18964c98472bd12f9b4554c33ac8ef8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 4e2629d020b75..44fbd9156a30f 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1736,6 +1736,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-6.12/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-6.12/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..998151c67b --- /dev/null +++ b/queue-6.12/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From 856493a1ac76a4a1d06747f06f3498d48e08da07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index 6c73e93afb478..57933576212bb 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1373,7 +1373,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-6.12/ntfs3-init-run-lock-for-extend-inode.patch b/queue-6.12/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..c344708fc9 --- /dev/null +++ b/queue-6.12/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From e0e4a8f7cc96630406b31f3c7b6ba289bcaa2bce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 44fbd9156a30f..8a9c11083e6e6 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -472,6 +472,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-6.12/objtool-fix-standalone-hacks-jump_label.patch b/queue-6.12/objtool-fix-standalone-hacks-jump_label.patch new file mode 100644 index 0000000000..4a083f1b91 --- /dev/null +++ b/queue-6.12/objtool-fix-standalone-hacks-jump_label.patch @@ -0,0 +1,44 @@ +From d87b4e77aa553a220fc669b929cffe08798e13f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 00:49:41 +0000 +Subject: objtool: Fix standalone --hacks=jump_label + +From: Dylan Hatch + +[ Upstream commit be8374a5ba7cbab6b97df94b4ffe0b92f5c8a6d2 ] + +The objtool command line 'objtool --hacks=jump_label foo.o' on its own +should be expected to rewrite jump labels to NOPs. This means the +add_special_section_alts() code path needs to run when only this option +is provided. + +This is mainly relevant in certain debugging situations, but could +potentially also fix kernel builds in which objtool is run with +--hacks=jump_label but without --orc, --stackval, --uaccess, or +--hacks=noinstr. + +Fixes: de6fbcedf5ab ("objtool: Read special sections with alts only when specific options are selected") +Signed-off-by: Dylan Hatch +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 59ca5b0c093d8..4adb3f3d9aed8 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2671,7 +2671,8 @@ static int decode_sections(struct objtool_file *file) + * Must be before add_jump_destinations(), which depends on 'func' + * being set for alternatives, to enable proper sibling call detection. + */ +- if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { ++ if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || ++ opts.hack_jump_label) { + ret = add_special_section_alts(file); + if (ret) + return ret; +-- +2.51.0 + diff --git a/queue-6.12/objtool-fix-weak-symbol-detection.patch b/queue-6.12/objtool-fix-weak-symbol-detection.patch new file mode 100644 index 0000000000..b467538b42 --- /dev/null +++ b/queue-6.12/objtool-fix-weak-symbol-detection.patch @@ -0,0 +1,65 @@ +From 6ec59f7a57c967c4c6aa95c772883eb055fb9b03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:27 -0700 +Subject: objtool: Fix weak symbol detection + +From: Josh Poimboeuf + +[ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] + +find_symbol_hole_containing() fails to find a symbol hole (aka stripped +weak symbol) if its section has no symbols before the hole. This breaks +weak symbol detection if -ffunction-sections is enabled. + +Fix that by allowing the interval tree to contain section symbols, which +are always at offset zero for a given section. + +Fixes a bunch of (-ffunction-sections) warnings like: + + vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction + +Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") +Acked-by: Petr Mladek +Tested-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 3d27983dc908d..19021f9755ac7 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -108,7 +108,7 @@ struct symbol_hole { + }; + + /* +- * Find !section symbol where @offset is after it. ++ * Find the last symbol before @offset. + */ + static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + { +@@ -119,8 +119,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + return -1; + + if (sh->key >= s->offset + s->len) { +- if (s->type != STT_SECTION) +- sh->sym = s; ++ sh->sym = s; + return 1; + } + +@@ -408,7 +407,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->len = sym->sym.st_size; + + __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { +- if (iter->offset == sym->offset && iter->type == sym->type) ++ if (iter->offset == sym->offset && iter->type == sym->type && ++ iter->len == sym->len) + iter->alias = sym; + } + +-- +2.51.0 + diff --git a/queue-6.12/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-6.12/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..fa111433df --- /dev/null +++ b/queue-6.12/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From edd2f119975bce4293105cfdb26551ced42180cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index aa595cd1ab6fe..6fcaaeece6666 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-6.12/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch b/queue-6.12/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch new file mode 100644 index 0000000000..7330b4b22c --- /dev/null +++ b/queue-6.12/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch @@ -0,0 +1,60 @@ +From 40122604de73975cfb2258c2bda1b1c34893da83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:04:14 -0700 +Subject: of: Skip devicetree kunit tests when RISCV+ACPI doesn't populate root + node + +From: Guenter Roeck + +[ Upstream commit 546dbb0223102813ffb5bbcb9443a47c3183f195 ] + +Starting with commit 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by +probing DT devices when ACPI is used"), riscv images no longer populate +devicetree if ACPI is enabled. This causes unit tests to fail which require +the root node to be set. + + # Subtest: of_dtb + # module: of_test + 1..2 + # of_dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:21 + Expected np is not null, but is + # of_dtb_root_node_found_by_path: pass:0 fail:1 skip:0 total:1 + not ok 1 of_dtb_root_node_found_by_path + # of_dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:31 + Expected of_root is not null, but is + # of_dtb_root_node_populates_of_root: pass:0 fail:1 skip:0 total:1 + not ok 2 of_dtb_root_node_populates_of_root + +Skip those tests for RISCV if the root node is not populated. + +Fixes: 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by probing DT devices when ACPI is used") +Cc: Han Gao +Cc: Paul Walmsley +Signed-off-by: Guenter Roeck +Reviewed-by: Paul Walmsley # arch/riscv +Link: https://patch.msgid.link/20251023160415.705294-1-linux@roeck-us.net +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/of_kunit_helpers.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/of/of_kunit_helpers.c b/drivers/of/of_kunit_helpers.c +index 7b3ed5a382aaa..f6ed1af8b62aa 100644 +--- a/drivers/of/of_kunit_helpers.c ++++ b/drivers/of/of_kunit_helpers.c +@@ -18,8 +18,9 @@ + */ + void of_root_kunit_skip(struct kunit *test) + { +- if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root) +- kunit_skip(test, "arm64+acpi doesn't populate a root node"); ++ if ((IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_RISCV)) && ++ IS_ENABLED(CONFIG_ACPI) && !of_root) ++ kunit_skip(test, "arm64/riscv+acpi doesn't populate a root node"); + } + EXPORT_SYMBOL_GPL(of_root_kunit_skip); + +-- +2.51.0 + diff --git a/queue-6.12/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-6.12/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..8b53d13471 --- /dev/null +++ b/queue-6.12/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From 88343bdd57ec6d4e1a46417bec86cea94806a1ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index 347ab74ac35aa..0fad7751490f5 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -97,7 +97,7 @@ + #define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-6.12/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-6.12/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..99d0dfa725 --- /dev/null +++ b/queue-6.12/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 3c0f2bf15cc29d34e365ded6aee464e3f28f588b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 4f75d13fe1dee..1c34ea8e7c61e 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1339,6 +1339,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-6.12/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch b/queue-6.12/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch new file mode 100644 index 0000000000..1788dce367 --- /dev/null +++ b/queue-6.12/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch @@ -0,0 +1,55 @@ +From 89faa3614945c3f36052190a532e6b8b572f4fe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 10:35:34 +0200 +Subject: PCI: rcar-gen2: Drop ARM dependency from PCI_RCAR_GEN2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit d312742f686582e6457070bcfd24bee8acfdf213 ] + +Since the reliance on ARM-specific struct pci_sys_data was removed, this +driver can be compile-tested on other architectures. + +While at it, make the help text a bit more generic, as some members of +the R-Car Gen2 family have a different number of internal PCI +controllers. + +Fixes: 4a957563fe0231e0 ("PCI: rcar-gen2: Convert to use modern host bridge probe functions") +Suggested-by: Ilpo Jarvinen +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: add rcar-gen2 to subject] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/00f75d6732eacce93f04ffaeedc415d2db714cd6.1759480426.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/Kconfig | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 9800b76810540..481acb03af80d 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -249,12 +249,11 @@ config PCIE_RCAR_EP + + config PCI_RCAR_GEN2 + bool "Renesas R-Car Gen2 Internal PCI controller" +- depends on ARCH_RENESAS || COMPILE_TEST +- depends on ARM ++ depends on (ARCH_RENESAS && ARM) || COMPILE_TEST + help + Say Y here if you want internal PCI support on R-Car Gen2 SoC. +- There are 3 internal PCI controllers available with a single +- built-in EHCI/OHCI host controller present on each one. ++ Each internal PCI controller contains a single built-in EHCI/OHCI ++ host controller. + + config PCIE_ROCKCHIP + bool +-- +2.51.0 + diff --git a/queue-6.12/perf-annotate-check-return-value-of-evsel__get_arch-.patch b/queue-6.12/perf-annotate-check-return-value-of-evsel__get_arch-.patch new file mode 100644 index 0000000000..3136737fb7 --- /dev/null +++ b/queue-6.12/perf-annotate-check-return-value-of-evsel__get_arch-.patch @@ -0,0 +1,39 @@ +From 47a3aa765cc3810ff85d7b0f21233bac483fed0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 15:30:05 +0800 +Subject: perf annotate: Check return value of evsel__get_arch() properly + +From: Tianyou Li + +[ Upstream commit f1204e5846d22fb2fffbd1164eeb19535f306797 ] + +Check the error code of evsel__get_arch() in the symbol__annotate(). +Previously it checked non-zero value but after the refactoring it does +only for negative values. + +Fixes: 0669729eb0afb0cf ("perf annotate: Factor out evsel__get_arch()") +Suggested-by: James Clark +Acked-by: Namhyung Kim +Signed-off-by: Tianyou Li +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/annotate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c +index 37ce43c4eb8f6..cb8f191e19fd9 100644 +--- a/tools/perf/util/annotate.c ++++ b/tools/perf/util/annotate.c +@@ -974,7 +974,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, + int err, nr; + + err = evsel__get_arch(evsel, &arch); +- if (err < 0) ++ if (err) + return err; + + if (parch) +-- +2.51.0 + diff --git a/queue-6.12/perf-arm-spe-extend-branch-operations.patch b/queue-6.12/perf-arm-spe-extend-branch-operations.patch new file mode 100644 index 0000000000..f1f48a792c --- /dev/null +++ b/queue-6.12/perf-arm-spe-extend-branch-operations.patch @@ -0,0 +1,94 @@ +From 959378f0c72384a2a7923f5203e441a172bf0614 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 11:12:35 +0000 +Subject: perf arm-spe: Extend branch operations + +From: Leo Yan + +[ Upstream commit 64d86c03e1441742216b6332bdfabfb6ede31662 ] + +In Arm ARM (ARM DDI 0487, L.a), the section "D18.2.7 Operation Type +packet", the branch subclass is extended for Call Return (CR), Guarded +control stack data access (GCS). + +This commit adds support CR and GCS operations. The IND (indirect) +operation is defined only in bit [1], its macro is updated accordingly. + +Move the COND (Conditional) macro into the same group with other +operations for better maintenance. + +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Leo Yan +Link: https://lore.kernel.org/r/20250304111240.3378214-8-leo.yan@arm.com +Signed-off-by: Namhyung Kim +Stable-dep-of: 33e1fffea492 ("perf arm_spe: Fix memset subclass in operation") +Signed-off-by: Sasha Levin +--- + .../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 12 +++++++++--- + .../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 11 ++++++++--- + 2 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index 4cef10a83962f..625834da7e20e 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -397,10 +397,16 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + + if (payload & SPE_OP_PKT_COND) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND"); +- +- if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload)) ++ if (payload & SPE_OP_PKT_INDIRECT_BRANCH) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND"); +- ++ if (payload & SPE_OP_PKT_GCS) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS"); ++ if (SPE_OP_PKT_CR_BL(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-BL"); ++ if (SPE_OP_PKT_CR_RET(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-RET"); ++ if (SPE_OP_PKT_CR_NON_BL_RET(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-NON-BL-RET"); + break; + default: + /* Unknown index */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index 464a912b221cd..32d760ede7013 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -7,6 +7,7 @@ + #ifndef INCLUDE__ARM_SPE_PKT_DECODER_H__ + #define INCLUDE__ARM_SPE_PKT_DECODER_H__ + ++#include + #include + #include + +@@ -116,8 +117,6 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_COND BIT(0) +- + #define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) + #define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 + #define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +@@ -148,7 +147,13 @@ enum arm_spe_events { + #define SPE_OP_PKT_SVE_PRED BIT(2) + #define SPE_OP_PKT_SVE_FP BIT(1) + +-#define SPE_OP_PKT_IS_INDIRECT_BRANCH(v) (((v) & GENMASK_ULL(7, 1)) == 0x2) ++#define SPE_OP_PKT_CR_MASK GENMASK_ULL(4, 3) ++#define SPE_OP_PKT_CR_BL(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 1) ++#define SPE_OP_PKT_CR_RET(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 2) ++#define SPE_OP_PKT_CR_NON_BL_RET(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 3) ++#define SPE_OP_PKT_GCS BIT(2) ++#define SPE_OP_PKT_INDIRECT_BRANCH BIT(1) ++#define SPE_OP_PKT_COND BIT(0) + + const char *arm_spe_pkt_name(enum arm_spe_pkt_type); + +-- +2.51.0 + diff --git a/queue-6.12/perf-arm_spe-fix-memset-subclass-in-operation.patch b/queue-6.12/perf-arm_spe-fix-memset-subclass-in-operation.patch new file mode 100644 index 0000000000..5f38700bd6 --- /dev/null +++ b/queue-6.12/perf-arm_spe-fix-memset-subclass-in-operation.patch @@ -0,0 +1,99 @@ +From cceba04ee379ad3ef62803f9d4b86fc0e3196513 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 18:24:27 +0000 +Subject: perf arm_spe: Fix memset subclass in operation + +From: Leo Yan + +[ Upstream commit 33e1fffea492b7158a168914dc0da6aedf78d08e ] + +The operation subclass is extracted from bits [7..1] of the payload. +Since bit [0] is not parsed, there is no chance to match the memset type +(0x25). As a result, the memset payload is never parsed successfully. + +Instead of extracting a unified bit field, change to extract the +specific bits for each operation subclass. + +Fixes: 34fb60400e32 ("perf arm-spe: Add raw decoding for SPEv1.3 MTE and MOPS load/store") +Signed-off-by: Leo Yan +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 ++++++------------- + .../arm-spe-decoder/arm-spe-pkt-decoder.h | 15 ++++++----- + 2 files changed, 14 insertions(+), 26 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index 625834da7e20e..a0a9b9cd13875 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -355,31 +355,20 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR"); + } + +- switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) { +- case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP: ++ if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_GP_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMSET: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET"); +- break; +- default: +- break; +- } + + if (SPE_OP_PKT_IS_LDST_SVE(payload)) { + /* SVE effective vector length */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index 32d760ede7013..0d947df9dd6ec 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -117,14 +117,13 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) +-#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 +-#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +-#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10 +-#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30 +-#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG 0x14 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY 0x20 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET 0x25 ++#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x0) ++#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(v) (((v) & GENMASK_ULL(7, 1)) == 0x4) ++#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x10) ++#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(v) (((v) & GENMASK_ULL(7, 1)) == 0x30) ++#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(v) (((v) & GENMASK_ULL(7, 1)) == 0x14) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(v) (((v) & GENMASK_ULL(7, 1)) == 0x20) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET(v) (((v) & GENMASK_ULL(7, 0)) == 0x25) + + #define SPE_OP_PKT_IS_LDST_ATOMIC(v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2) + +-- +2.51.0 + diff --git a/queue-6.12/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch b/queue-6.12/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch new file mode 100644 index 0000000000..414d65e1bb --- /dev/null +++ b/queue-6.12/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch @@ -0,0 +1,42 @@ +From 61c88eaecd2570ef0bbee036279e15f10764ecb4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 00:19:18 -0800 +Subject: perf hist: In init, ensure mem_info is put on error paths + +From: Ian Rogers + +[ Upstream commit f60efb4454b24cc944ff3eac164bb9dce9169f71 ] + +Rather than exit the internal map_symbols directly, put the mem-info +that does this and also lowers the reference count on the mem-info +itself otherwise the mem-info is being leaked. + +Fixes: 56e144fe98260a0f ("perf mem_info: Add and use map_symbol__exit and addr_map_symbol__exit") +Signed-off-by: Ian Rogers +Reviewed-by: Arnaldo Carvalho de Melo +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hist.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c +index f387e85a00873..694faf405e11c 100644 +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -528,10 +528,8 @@ static int hist_entry__init(struct hist_entry *he, + map_symbol__exit(&he->branch_info->to.ms); + zfree(&he->branch_info); + } +- if (he->mem_info) { +- map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms); +- map_symbol__exit(&mem_info__daddr(he->mem_info)->ms); +- } ++ if (he->mem_info) ++ mem_info__zput(he->mem_info); + err: + map_symbol__exit(&he->ms); + zfree(&he->stat_acc); +-- +2.51.0 + diff --git a/queue-6.12/perf-lock-contention-load-kernel-map-before-lookup.patch b/queue-6.12/perf-lock-contention-load-kernel-map-before-lookup.patch new file mode 100644 index 0000000000..660f1d8eab --- /dev/null +++ b/queue-6.12/perf-lock-contention-load-kernel-map-before-lookup.patch @@ -0,0 +1,56 @@ +From 89f970131bc092305a1da402326e7b1bb7d049f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 21:01:39 -0700 +Subject: perf lock contention: Load kernel map before lookup + +From: Namhyung Kim + +[ Upstream commit 553d18c98a896094b99a01765b9698b204183d49 ] + +On some machines, it caused troubles when it tried to find kernel +symbols. I think it's because kernel modules and kallsyms are messed +up during load and split. + +Basically we want to make sure the kernel map is loaded and the code has +it in the lock_contention_read(). But recently we added more lookups in +the lock_contention_prepare() which is called before _read(). + +Also the kernel map (kallsyms) may not be the first one in the group +like on ARM. Let's use machine__kernel_map() rather than just loading +the first map. + +Reviewed-by: Ian Rogers +Fixes: 688d2e8de231c54e ("perf lock contention: Add -l/--lock-addr option") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_lock_contention.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c +index 41a1ad0878951..a286e15b16a4e 100644 +--- a/tools/perf/util/bpf_lock_contention.c ++++ b/tools/perf/util/bpf_lock_contention.c +@@ -26,6 +26,9 @@ int lock_contention_prepare(struct lock_contention *con) + struct evlist *evlist = con->evlist; + struct target *target = con->target; + ++ /* make sure it loads the kernel map before lookup */ ++ map__load(machine__kernel_map(con->machine)); ++ + skel = lock_contention_bpf__open(); + if (!skel) { + pr_err("Failed to open lock-contention BPF skeleton\n"); +@@ -443,9 +446,6 @@ int lock_contention_read(struct lock_contention *con) + bpf_prog_test_run_opts(prog_fd, &opts); + } + +- /* make sure it loads the kernel map */ +- maps__load_first(machine->kmaps); +- + prev_key = NULL; + while (!bpf_map_get_next_key(fd, prev_key, &key)) { + s64 ls_key; +-- +2.51.0 + diff --git a/queue-6.12/perf-record-skip-synthesize-event-when-open-evsel-fa.patch b/queue-6.12/perf-record-skip-synthesize-event-when-open-evsel-fa.patch new file mode 100644 index 0000000000..881e105136 --- /dev/null +++ b/queue-6.12/perf-record-skip-synthesize-event-when-open-evsel-fa.patch @@ -0,0 +1,71 @@ +From bacff5f20e35692cc7eb054fe4c87bae5bb33a90 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:50:43 +0800 +Subject: perf record: skip synthesize event when open evsel failed + +From: Shuai Xue + +[ Upstream commit 163e5f2b96632b7fb2eaa965562aca0dbdf9f996 ] + +When using perf record with the `--overwrite` option, a segmentation fault +occurs if an event fails to open. For example: + + perf record -e cycles-ct -F 1000 -a --overwrite + Error: + cycles-ct:H: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + perf: Segmentation fault + #0 0x6466b6 in dump_stack debug.c:366 + #1 0x646729 in sighandler_dump_stack debug.c:378 + #2 0x453fd1 in sigsegv_handler builtin-record.c:722 + #3 0x7f8454e65090 in __restore_rt libc-2.32.so[54090] + #4 0x6c5671 in __perf_event__synthesize_id_index synthetic-events.c:1862 + #5 0x6c5ac0 in perf_event__synthesize_id_index synthetic-events.c:1943 + #6 0x458090 in record__synthesize builtin-record.c:2075 + #7 0x45a85a in __cmd_record builtin-record.c:2888 + #8 0x45deb6 in cmd_record builtin-record.c:4374 + #9 0x4e5e33 in run_builtin perf.c:349 + #10 0x4e60bf in handle_internal_command perf.c:401 + #11 0x4e6215 in run_argv perf.c:448 + #12 0x4e653a in main perf.c:555 + #13 0x7f8454e4fa72 in __libc_start_main libc-2.32.so[3ea72] + #14 0x43a3ee in _start ??:0 + +The --overwrite option implies --tail-synthesize, which collects non-sample +events reflecting the system status when recording finishes. However, when +evsel opening fails (e.g., unsupported event 'cycles-ct'), session->evlist +is not initialized and remains NULL. The code unconditionally calls +record__synthesize() in the error path, which iterates through the NULL +evlist pointer and causes a segfault. + +To fix it, move the record__synthesize() call inside the error check block, so +it's only called when there was no error during recording, ensuring that evlist +is properly initialized. + +Fixes: 4ea648aec019 ("perf record: Add --tail-synthesize option") +Signed-off-by: Shuai Xue +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c +index ab9035573a15e..e5578bd41d3bb 100644 +--- a/tools/perf/builtin-record.c ++++ b/tools/perf/builtin-record.c +@@ -2832,11 +2832,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) + rec->bytes_written += off_cpu_write(rec->session); + + record__read_lost_samples(rec); +- record__synthesize(rec, true); + /* this will be recalculated during process_buildids() */ + rec->samples = 0; + + if (!err) { ++ record__synthesize(rec, true); + if (!rec->timestamp_filename) { + record__finish_output(rec); + } else { +-- +2.51.0 + diff --git a/queue-6.12/perf-remove-get_perf_callchain-init_nr-argument.patch b/queue-6.12/perf-remove-get_perf_callchain-init_nr-argument.patch new file mode 100644 index 0000000000..61776795af --- /dev/null +++ b/queue-6.12/perf-remove-get_perf_callchain-init_nr-argument.patch @@ -0,0 +1,109 @@ +From 47bd613ff4a23ec9a6b463dd212260ae2573ce45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Aug 2025 14:03:39 -0400 +Subject: perf: Remove get_perf_callchain() init_nr argument + +From: Josh Poimboeuf + +[ Upstream commit e649bcda25b5ae1a30a182cc450f928a0b282c93 ] + +The 'init_nr' argument has double duty: it's used to initialize both the +number of contexts and the number of stack entries. That's confusing +and the callers always pass zero anyway. Hard code the zero. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Namhyung Kim +Acked-by: Alexei Starovoitov +Link: https://lore.kernel.org/r/20250820180428.259565081@kernel.org +Stable-dep-of: 23f852daa4ba ("bpf: Fix stackmap overflow check in __bpf_get_stackid()") +Signed-off-by: Sasha Levin +--- + include/linux/perf_event.h | 2 +- + kernel/bpf/stackmap.c | 4 ++-- + kernel/events/callchain.c | 12 ++++++------ + kernel/events/core.c | 2 +- + 4 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index ce64b4b937f06..c2bd4bc45a27b 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1602,7 +1602,7 @@ DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); + extern void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); + extern void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); + extern struct perf_callchain_entry * +-get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, ++get_perf_callchain(struct pt_regs *regs, bool kernel, bool user, + u32 max_stack, bool crosstask, bool add_mark); + extern int get_callchain_buffers(int max_stack); + extern void put_callchain_buffers(void); +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index 3615c06b7dfa9..ec3a57a5fba1f 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -314,7 +314,7 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, + if (max_depth > sysctl_perf_event_max_stack) + max_depth = sysctl_perf_event_max_stack; + +- trace = get_perf_callchain(regs, 0, kernel, user, max_depth, ++ trace = get_perf_callchain(regs, kernel, user, max_depth, + false, false); + + if (unlikely(!trace)) +@@ -451,7 +451,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + else if (kernel && task) + trace = get_callchain_entry_for_task(task, max_depth); + else +- trace = get_perf_callchain(regs, 0, kernel, user, max_depth, ++ trace = get_perf_callchain(regs, kernel, user, max_depth, + crosstask, false); + + if (unlikely(!trace) || trace->nr < skip) { +diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c +index 49d87e6db553f..677901f456a94 100644 +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -216,7 +216,7 @@ static void fixup_uretprobe_trampoline_entries(struct perf_callchain_entry *entr + } + + struct perf_callchain_entry * +-get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, ++get_perf_callchain(struct pt_regs *regs, bool kernel, bool user, + u32 max_stack, bool crosstask, bool add_mark) + { + struct perf_callchain_entry *entry; +@@ -231,11 +231,11 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, + if (!entry) + return NULL; + +- ctx.entry = entry; +- ctx.max_stack = max_stack; +- ctx.nr = entry->nr = init_nr; +- ctx.contexts = 0; +- ctx.contexts_maxed = false; ++ ctx.entry = entry; ++ ctx.max_stack = max_stack; ++ ctx.nr = entry->nr = 0; ++ ctx.contexts = 0; ++ ctx.contexts_maxed = false; + + if (kernel && !user_mode(regs)) { + if (add_mark) +diff --git a/kernel/events/core.c b/kernel/events/core.c +index d6a86d8e9e59b..6bc8b84f12156 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -7860,7 +7860,7 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) + if (!kernel && !user) + return &__empty_callchain; + +- callchain = get_perf_callchain(regs, 0, kernel, user, ++ callchain = get_perf_callchain(regs, kernel, user, + max_stack, crosstask, true); + return callchain ?: &__empty_callchain; + } +-- +2.51.0 + diff --git a/queue-6.12/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-6.12/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..58ec1f15b7 --- /dev/null +++ b/queue-6.12/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From 60defe911658d7f25cfba423d93d3be94bcd274c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index c60e38dc39db7..249de806f8e0d 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -938,11 +938,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + map__zput(curr_map); +-- +2.51.0 + diff --git a/queue-6.12/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch b/queue-6.12/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch new file mode 100644 index 0000000000..8c32dc9dd6 --- /dev/null +++ b/queue-6.12/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch @@ -0,0 +1,41 @@ +From 9a2183d78bf762261c9c19ccae7afecd05c3443b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:14 -0800 +Subject: perf tools: Mark split kallsyms DSOs as loaded + +From: Namhyung Kim + +[ Upstream commit 7da4d60db33cccd8f4c445ab20bba71531435ee5 ] + +The maps__split_kallsyms() will split symbols to module DSOs if it comes +from a module. It also handled some unusual kernel symbols after modules +by creating new kernel maps like "[kernel].0". + +But they are pseudo DSOs to have those unexpected symbols. They should +not be considered as unloaded kernel DSOs. Otherwise the dso__load() +for them will end up calling dso__load_kallsyms() and then +maps__split_kallsyms() again and again. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index c0ec5ed4f1aa4..c60e38dc39db7 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -950,6 +950,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + return -1; + + dso__set_kernel(ndso, dso__kernel(dso)); ++ dso__set_loaded(ndso); + + curr_map = map__new2(pos->start, ndso); + if (curr_map == NULL) { +-- +2.51.0 + diff --git a/queue-6.12/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-6.12/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..af61166691 --- /dev/null +++ b/queue-6.12/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From 98badd6a37057f6099a7cc78d1a9ffc1fd4f191b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index acc0774519ce2..4a57a9948c745 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3872,7 +3872,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-6.12/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch b/queue-6.12/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch new file mode 100644 index 0000000000..2d8e3697bc --- /dev/null +++ b/queue-6.12/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch @@ -0,0 +1,47 @@ +From 35382759ddc40eca64f65d9c8d40fdd3c530e69b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:37:52 -0700 +Subject: perf/x86/intel/cstate: Remove PC3 support from LunarLake + +From: Zhang Rui + +[ Upstream commit 4ba45f041abe60337fdeeb68553b9ee1217d544e ] + +LunarLake doesn't support Package C3. Remove the PC3 residency counter +support from LunarLake. + +Fixes: 26579860fbd5 ("perf/x86/intel/cstate: Add Lunarlake support") +Signed-off-by: Zhang Rui +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Kan Liang +Reviewed-by: Dapeng Mi +Link: https://patch.msgid.link/20251023223754.1743928-3-zide.chen@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/cstate.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index ae4ec16156bb0..aee2dfc108408 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -70,7 +70,7 @@ + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, + * GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL, +- * ADL,RPL,MTL,ARL,LNL ++ * ADL,RPL,MTL,ARL + * Scope: Package (physical package) + * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. + * perf code: 0x02 +@@ -521,7 +521,6 @@ static const struct cstate_model lnl_cstates __initconst = { + BIT(PERF_CSTATE_CORE_C7_RES), + + .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | +- BIT(PERF_CSTATE_PKG_C3_RES) | + BIT(PERF_CSTATE_PKG_C6_RES) | + BIT(PERF_CSTATE_PKG_C10_RES), + }; +-- +2.51.0 + diff --git a/queue-6.12/phy-freescale-initialize-priv-lock.patch b/queue-6.12/phy-freescale-initialize-priv-lock.patch new file mode 100644 index 0000000000..ac2cf77159 --- /dev/null +++ b/queue-6.12/phy-freescale-initialize-priv-lock.patch @@ -0,0 +1,71 @@ +From 739f77bdaee442847327b6fa64796cb09eb03f13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 09:38:06 +0800 +Subject: phy: freescale: Initialize priv->lock + +From: Xiaolei Wang + +[ Upstream commit 95e5905698983df94069e185f9eb3c67c7cf75d5 ] + +Initialize priv->lock to fix the following warning. + +WARNING: CPU: 0 PID: 12 at kernel/locking/mutex.c:577 __mutex_lock+0x70c/0x8b8 + Modules linked in: + Hardware name: Freescale i.MX8QM MEK (DT) + Call trace: + __mutex_lock+0x70c/0x8b8 (P) + mutex_lock_nested+0x24/0x30 + imx_hsio_power_on+0x4c/0x764 + phy_power_on+0x7c/0x12c + imx_pcie_host_init+0x1d0/0x4d4 + dw_pcie_host_init+0x188/0x4b0 + imx_pcie_probe+0x324/0x6f4 + platform_probe+0x5c/0x98 + really_probe+0xbc/0x29c + __driver_probe_device+0x78/0x12c + driver_probe_device+0xd8/0x160 + __device_attach_driver+0xb8/0x138 + bus_for_each_drv+0x84/0xe4 + __device_attach_async_helper+0xb8/0xdc + async_run_entry_fn+0x34/0xe0 + process_one_work+0x220/0x694 + worker_thread+0x1c0/0x36c + kthread+0x14c/0x224 + +Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support") +Signed-off-by: Xiaolei Wang +Reviewed-by: Frank Li +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20250925013806.569658-1-xiaolei.wang@windriver.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +index 5dca93cd325c8..977d21d753a59 100644 +--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c ++++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +@@ -533,7 +533,7 @@ static struct phy *imx_hsio_xlate(struct device *dev, + + static int imx_hsio_probe(struct platform_device *pdev) + { +- int i; ++ int i, ret; + void __iomem *off; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; +@@ -545,6 +545,9 @@ static int imx_hsio_probe(struct platform_device *pdev) + return -ENOMEM; + priv->dev = &pdev->dev; + priv->drvdata = of_device_get_match_data(dev); ++ ret = devm_mutex_init(dev, &priv->lock); ++ if (ret) ++ return ret; + + /* Get HSIO configuration mode */ + if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg)) +-- +2.51.0 + diff --git a/queue-6.12/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-6.12/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..22c3421b53 --- /dev/null +++ b/queue-6.12/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From a433a0db18619550c0bee08a73712b60cb607915 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index 19983b206405c..a8e587dd96c5c 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2595,7 +2595,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2616,12 +2616,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-6.12/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch b/queue-6.12/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch new file mode 100644 index 0000000000..9cad80301e --- /dev/null +++ b/queue-6.12/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch @@ -0,0 +1,94 @@ +From b7875dc5a36f11a008706f9c61861cd2fcc51a03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 16:58:05 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Fix an error handling path in + rcar_gen3_phy_usb2_probe() + +From: Christophe JAILLET + +[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ] + +If an error occurs after the reset_control_deassert(), +reset_control_assert() must be called, as already done in the remove +function. + +Use devm_add_action_or_reset() to add the missing call and simplify the +.remove() function accordingly. + +While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. + +[claudiu.beznea: removed "struct reset_control *rstc = data;" from + rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] + +Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") +Signed-off-by: Christophe JAILLET +Reviewed-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Tested-by: Wolfram Sang +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index b45aee8f59644..256c807e7066d 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -117,7 +117,6 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; +- struct reset_control *rstc; + struct work_struct work; + spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; +@@ -671,21 +670,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static void rcar_gen3_reset_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) + { + struct device *dev = channel->dev; ++ struct reset_control *rstc; + int ret; + u32 val; + +- channel->rstc = devm_reset_control_array_get_shared(dev); +- if (IS_ERR(channel->rstc)) +- return PTR_ERR(channel->rstc); ++ rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(rstc)) ++ return PTR_ERR(rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + +- ret = reset_control_deassert(channel->rstc); ++ ret = reset_control_deassert(rstc); ++ if (ret) ++ goto rpm_put; ++ ++ ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); + if (ret) + goto rpm_put; + +@@ -830,7 +839,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + +- reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + }; + +-- +2.51.0 + diff --git a/queue-6.12/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch b/queue-6.12/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch new file mode 100644 index 0000000000..5501328ac9 --- /dev/null +++ b/queue-6.12/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch @@ -0,0 +1,59 @@ +From 82d1c8e30f981fc25f74ee2be1ec609db5400040 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:56 +0200 +Subject: phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding + the limits + +From: Cristian Ciocaltea + +[ Upstream commit 51023cf6cc5db3423dea6620746d9087e336e024 ] + +Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of +other lanes. It's worth noting this might only happen when dealing with +HDMI 2.0 rates. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-3-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index d287e818fb03c..3d0950048ef96 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -553,13 +553,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { + + static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0312), 0x00), +- REG_SEQ0(LANE_REG(031e), 0x00), + REG_SEQ0(LANE_REG(0412), 0x00), +- REG_SEQ0(LANE_REG(041e), 0x00), + REG_SEQ0(LANE_REG(0512), 0x00), +- REG_SEQ0(LANE_REG(051e), 0x00), + REG_SEQ0(LANE_REG(0612), 0x00), +- REG_SEQ0(LANE_REG(061e), 0x08), + REG_SEQ0(LANE_REG(0303), 0x2f), + REG_SEQ0(LANE_REG(0403), 0x2f), + REG_SEQ0(LANE_REG(0503), 0x2f), +@@ -572,6 +568,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0406), 0x1c), + REG_SEQ0(LANE_REG(0506), 0x1c), + REG_SEQ0(LANE_REG(0606), 0x1c), ++ /* Keep Inter-Pair Skew in the limits */ ++ REG_SEQ0(LANE_REG(031e), 0x02), ++ REG_SEQ0(LANE_REG(041e), 0x02), ++ REG_SEQ0(LANE_REG(051e), 0x02), ++ REG_SEQ0(LANE_REG(061e), 0x0a), + }; + + static bool rk_hdptx_phy_is_rw_reg(struct device *dev, unsigned int reg) +-- +2.51.0 + diff --git a/queue-6.12/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch b/queue-6.12/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch new file mode 100644 index 0000000000..12a48501cc --- /dev/null +++ b/queue-6.12/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch @@ -0,0 +1,53 @@ +From 85f2fd9da81c02414450457893fd655a1251a21e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:55 +0200 +Subject: phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth + +From: Cristian Ciocaltea + +[ Upstream commit 8daaced9f5eeb4a2c8ca08b0a8286b6a498a8387 ] + +Due to its relatively low frequency, a noise stemming from the 24MHz PLL +reference clock may traverse the low-pass loop filter of ROPLL, which +could potentially generate some HDMI flash artifacts. + +Reduce ROPLL loop bandwidth in an attempt to mitigate the problem. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-2-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 5547f8df8e717..d287e818fb03c 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -385,9 +385,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0043), 0x00), + REG_SEQ0(CMN_REG(0044), 0x46), + REG_SEQ0(CMN_REG(0045), 0x24), +- REG_SEQ0(CMN_REG(0046), 0xff), + REG_SEQ0(CMN_REG(0047), 0x00), +- REG_SEQ0(CMN_REG(0048), 0x44), + REG_SEQ0(CMN_REG(0049), 0xfa), + REG_SEQ0(CMN_REG(004a), 0x08), + REG_SEQ0(CMN_REG(004b), 0x00), +@@ -460,6 +458,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0034), 0x00), + REG_SEQ0(CMN_REG(003d), 0x40), + REG_SEQ0(CMN_REG(0042), 0x78), ++ REG_SEQ0(CMN_REG(0046), 0xdd), ++ REG_SEQ0(CMN_REG(0048), 0x11), + REG_SEQ0(CMN_REG(004e), 0x34), + REG_SEQ0(CMN_REG(005c), 0x25), + REG_SEQ0(CMN_REG(005e), 0x4f), +-- +2.51.0 + diff --git a/queue-6.12/pinctrl-renesas-rzg2l-fix-pmc-restore.patch b/queue-6.12/pinctrl-renesas-rzg2l-fix-pmc-restore.patch new file mode 100644 index 0000000000..2d89ace427 --- /dev/null +++ b/queue-6.12/pinctrl-renesas-rzg2l-fix-pmc-restore.patch @@ -0,0 +1,41 @@ +From 61ab24a7f4bc62d991ce7067b837c1ca8ac2747b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 12:15:52 +0100 +Subject: pinctrl: renesas: rzg2l: Fix PMC restore + +From: Biju Das + +[ Upstream commit cea950101108b7bfffe26ec4007b8e263a4b56a8 ] + +PMC restore needs unlocking the register using the PWPR register. + +Fixes: ede014cd1ea6422d ("pinctrl: renesas: rzg2l: Add function pointer for PMC register write") +Signed-off-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250921111557.103069-2-biju.das.jz@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +index 698ab8cc970a6..c6ef77472d9a1 100644 +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -2807,7 +2807,11 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen + * Now cache the registers or set them in the order suggested by + * HW manual (section "Operation for GPIO Function"). + */ +- RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ if (suspend) ++ RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ else ++ pctrl->data->pmc_writeb(pctrl, cache->pmc[port], PMC(off)); ++ + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off), + cache->iolh[0][port]); +-- +2.51.0 + diff --git a/queue-6.12/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-6.12/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..d5ae650cde --- /dev/null +++ b/queue-6.12/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From db7def1782c7a2a54dba3524f60b21e790ccb2aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 1df0a00ae1ee8..2218d65a7d842 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -485,7 +485,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -549,9 +550,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-6.12/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.12/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..6d433105eb --- /dev/null +++ b/queue-6.12/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From 62510a61dcccf4b75a8b85838e914c186c1852f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 2659a854a514e..857ce101fab0c 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1537,7 +1537,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-6.12/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-6.12/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..988119f654 --- /dev/null +++ b/queue-6.12/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From 2e4bc465bbfa2284550b1efd9996885fc4a8a049 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 8ef1b6f1f7879..2dbb474acea67 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -364,7 +364,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-6.12/power-supply-cw2015-check-devm_delayed_work_autocanc.patch b/queue-6.12/power-supply-cw2015-check-devm_delayed_work_autocanc.patch new file mode 100644 index 0000000000..1b77f1586d --- /dev/null +++ b/queue-6.12/power-supply-cw2015-check-devm_delayed_work_autocanc.patch @@ -0,0 +1,46 @@ +From 082586bdb65dc8d89eb202726a264798edb2b56b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:07:11 +0300 +Subject: power: supply: cw2015: Check devm_delayed_work_autocancel() return + code + +From: Ivan Abramov + +[ Upstream commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 ] + +Since devm_delayed_work_autocancel() may fail, add return code check and +exit cw_bat_probe() on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/cw2015_battery.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 382dff8805c62..f41ce7e41fac9 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -702,7 +702,13 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ if (ret) { ++ dev_err_probe(&client->dev, ret, ++ "Failed to register delayed work\n"); ++ return ret; ++ } ++ + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +-- +2.51.0 + diff --git a/queue-6.12/power-supply-max17040-check-iio_read_channel_process.patch b/queue-6.12/power-supply-max17040-check-iio_read_channel_process.patch new file mode 100644 index 0000000000..45a9da4058 --- /dev/null +++ b/queue-6.12/power-supply-max17040-check-iio_read_channel_process.patch @@ -0,0 +1,50 @@ +From 488f3068f57c9a2409d4fd4d52157fa77f279912 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:36:47 +0300 +Subject: power: supply: max17040: Check iio_read_channel_processed() return + code + +From: Ivan Abramov + +[ Upstream commit 2c68ac48c52ad146523f32b01d70009622bf81aa ] + +Since iio_read_channel_processed() may fail, return its exit code on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 814755c48f8b ("power: max17040: get thermal data from adc if available") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008133648.559286-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/max17040_battery.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c +index c1640bc6accd2..48453508688a4 100644 +--- a/drivers/power/supply/max17040_battery.c ++++ b/drivers/power/supply/max17040_battery.c +@@ -388,6 +388,7 @@ static int max17040_get_property(struct power_supply *psy, + union power_supply_propval *val) + { + struct max17040_chip *chip = power_supply_get_drvdata(psy); ++ int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +@@ -410,7 +411,10 @@ static int max17040_get_property(struct power_supply *psy, + if (!chip->channel_temp) + return -ENODATA; + +- iio_read_channel_processed(chip->channel_temp, &val->intval); ++ ret = iio_read_channel_processed(chip->channel_temp, &val->intval); ++ if (ret) ++ return ret; ++ + val->intval /= 100; /* Convert from milli- to deci-degree */ + + break; +-- +2.51.0 + diff --git a/queue-6.12/power-supply-rt5033_charger-fix-device-node-referenc.patch b/queue-6.12/power-supply-rt5033_charger-fix-device-node-referenc.patch new file mode 100644 index 0000000000..f255462b48 --- /dev/null +++ b/queue-6.12/power-supply-rt5033_charger-fix-device-node-referenc.patch @@ -0,0 +1,41 @@ +From 0259466d8a1f10d8ac8e6f16dfed8992f7675044 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 19:32:34 +0800 +Subject: power: supply: rt5033_charger: Fix device node reference leaks + +From: Haotian Zhang + +[ Upstream commit 6cdc4d488c2f3a61174bfba4e8cc4ac92c219258 ] + +The device node pointers `np_conn` and `np_edev`, obtained from +of_parse_phandle() and of_get_parent() respectively, are not released. +This results in a reference count leak. + +Add of_node_put() calls after the last use of these device nodes to +properly release their references and fix the leaks. + +Fixes: 8242336dc8a8 ("power: supply: rt5033_charger: Add cable detection and USB OTG supply") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20250929113234.1726-1-vulab@iscas.ac.cn +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt5033_charger.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/power/supply/rt5033_charger.c b/drivers/power/supply/rt5033_charger.c +index d19c7e80a92aa..c7d82a8065917 100644 +--- a/drivers/power/supply/rt5033_charger.c ++++ b/drivers/power/supply/rt5033_charger.c +@@ -700,6 +700,8 @@ static int rt5033_charger_probe(struct platform_device *pdev) + np_conn = of_parse_phandle(pdev->dev.of_node, "richtek,usb-connector", 0); + np_edev = of_get_parent(np_conn); + charger->edev = extcon_find_edev_by_node(np_edev); ++ of_node_put(np_edev); ++ of_node_put(np_conn); + if (IS_ERR(charger->edev)) { + dev_warn(charger->dev, "no extcon device found in device-tree\n"); + goto out; +-- +2.51.0 + diff --git a/queue-6.12/power-supply-rt9467-prevent-using-uninitialized-loca.patch b/queue-6.12/power-supply-rt9467-prevent-using-uninitialized-loca.patch new file mode 100644 index 0000000000..7af3d4d561 --- /dev/null +++ b/queue-6.12/power-supply-rt9467-prevent-using-uninitialized-loca.patch @@ -0,0 +1,40 @@ +From d3e7fb346c031bf04a70d077de4984b5559e1776 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:53:08 +0300 +Subject: power: supply: rt9467: Prevent using uninitialized local variable in + rt9467_set_value_from_ranges() + +From: Murad Masimov + +[ Upstream commit 15aca30cc6c69806054b896a2ccf7577239cb878 ] + +There is a typo in rt9467_set_value_from_ranges() that can cause leaving local +variable sel with an undefined value which is then used in regmap_field_write(). + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Murad Masimov +Link: https://patch.msgid.link/20251009145308.1830893-1-m.masimov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index faa5de2857ea0..be65b0f517210 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -376,7 +376,7 @@ static int rt9467_set_value_from_ranges(struct rt9467_chg_data *data, + if (rsel == RT9467_RANGE_VMIVR) { + ret = linear_range_get_selector_high(range, value, &sel, &found); + if (ret) +- value = range->max_sel; ++ sel = range->max_sel; + } else { + linear_range_get_selector_within(range, value, &sel); + } +-- +2.51.0 + diff --git a/queue-6.12/power-supply-rt9467-return-error-on-failure-in-rt946.patch b/queue-6.12/power-supply-rt9467-return-error-on-failure-in-rt946.patch new file mode 100644 index 0000000000..cd96ae1e0b --- /dev/null +++ b/queue-6.12/power-supply-rt9467-return-error-on-failure-in-rt946.patch @@ -0,0 +1,44 @@ +From 581f88689d03f0c619c0ea1b322ea30a3aee01d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:47:24 +0300 +Subject: power: supply: rt9467: Return error on failure in + rt9467_set_value_from_ranges() + +From: Ivan Abramov + +[ Upstream commit 8b27fe2d8d2380118c343629175385ff587e2fe4 ] + +The return value of rt9467_set_value_from_ranges() when setting AICL VTH is +not checked, even though it may fail. + +Log error and return from rt9467_run_aicl() on fail. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009144725.562278-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index 235169c85c5d8..faa5de2857ea0 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -588,6 +588,10 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) + aicl_vth = mivr_vth + RT9467_AICLVTH_GAP_uV; + ret = rt9467_set_value_from_ranges(data, F_AICL_VTH, + RT9467_RANGE_AICL_VTH, aicl_vth); ++ if (ret) { ++ dev_err(data->dev, "Failed to set AICL VTH\n"); ++ return ret; ++ } + + /* Trigger AICL function */ + ret = regmap_field_write(data->rm_field[F_AICL_MEAS], 1); +-- +2.51.0 + diff --git a/queue-6.12/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-6.12/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..f3ccc5b8cc --- /dev/null +++ b/queue-6.12/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From ada232d9cd613a4536b1f3aec14051b8dced8e9e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index d56e499ac59fb..10f3ecf5af72f 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.12/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-6.12/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..e93871ab1e --- /dev/null +++ b/queue-6.12/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From 07102a50d18b882328d2d67633346a5dd408a051 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index f4a8c98772491..1beb578c64114 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -263,10 +263,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -306,10 +305,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-6.12/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch b/queue-6.12/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch new file mode 100644 index 0000000000..afb106dc13 --- /dev/null +++ b/queue-6.12/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch @@ -0,0 +1,82 @@ +From 5e2dc8388eba2cc0d3c74b4336281ff8d4dff7aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:27 +0530 +Subject: powerpc/64s/hash: Restrict stress_hpt_struct memblock region to + within RMA limit + +From: Ritesh Harjani (IBM) + +[ Upstream commit 17b45ccf09882e0c808ad2cf62acdc90ad968746 ] + +When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real +Addressing Mode during early boot. During this, we should ensure that +memory region allocations for stress_hpt_struct should happen from +within RMA region as otherwise the boot might get stuck while doing +memset of this region. + +History behind why do we have RMA region limitation is better explained +in these 2 patches [1] & [2]. This patch ensures that memset to +stress_hpt_struct during early boot does not cross ppc64_rma_size +boundary. + +[1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/ +[2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/ + +Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/hash_utils.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c +index e1eadd03f1339..9914d89f9db7d 100644 +--- a/arch/powerpc/mm/book3s64/hash_utils.c ++++ b/arch/powerpc/mm/book3s64/hash_utils.c +@@ -1039,11 +1039,14 @@ static void __init htab_initialize(void) + unsigned long table; + unsigned long pteg_count; + unsigned long prot; +- phys_addr_t base = 0, size = 0, end; ++ phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; + u64 i; + + DBG(" -> htab_initialize()\n"); + ++ if (firmware_has_feature(FW_FEATURE_LPAR)) ++ limit = ppc64_rma_size; ++ + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { + mmu_kernel_ssize = MMU_SEGSIZE_1T; + mmu_highuser_ssize = MMU_SEGSIZE_1T; +@@ -1059,7 +1062,7 @@ static void __init htab_initialize(void) + // Too early to use nr_cpu_ids, so use NR_CPUS + tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, + __alignof__(struct stress_hpt_struct), +- 0, MEMBLOCK_ALLOC_ANYWHERE); ++ MEMBLOCK_LOW_LIMIT, limit); + memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); + stress_hpt_struct = __va(tmp); + +@@ -1093,7 +1096,6 @@ static void __init htab_initialize(void) + mmu_hash_ops.hpte_clear_all(); + #endif + } else { +- unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; + + #ifdef CONFIG_PPC_CELL + /* +@@ -1109,7 +1111,7 @@ static void __init htab_initialize(void) + + table = memblock_phys_alloc_range(htab_size_bytes, + htab_size_bytes, +- 0, limit); ++ MEMBLOCK_LOW_LIMIT, limit); + if (!table) + panic("ERROR: Failed to allocate %pa bytes below %pa\n", + &htab_size_bytes, &limit); +-- +2.51.0 + diff --git a/queue-6.12/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-6.12/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..56833a86c9 --- /dev/null +++ b/queue-6.12/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From eb263634b67e80f53ed3c46df4090eed0d04e5c6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index a6baa6166d940..671d0dc00c6d0 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-6.12/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch b/queue-6.12/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch new file mode 100644 index 0000000000..6b63b65644 --- /dev/null +++ b/queue-6.12/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch @@ -0,0 +1,83 @@ +From 51d905e9ccb57ba0091ec670355a4e8b6622f086 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 09:09:41 +0530 +Subject: powerpc/kdump: Fix size calculation for hot-removed memory ranges + +From: Sourabh Jain + +[ Upstream commit 7afe2383eff05f76f4ce2cfda658b7889c89f101 ] + +The elfcorehdr segment in the kdump image stores information about the +memory regions (called crash memory ranges) that the kdump kernel must +capture. + +When a memory hot-remove event occurs, the kernel regenerates the +elfcorehdr for the currently loaded kdump image to remove the +hot-removed memory from the crash memory ranges. + +Call chain: +remove_mem_range() +update_crash_elfcorehdr() +arch_crash_handle_hotplug_event() +crash_handle_hotplug_event() + +While removing the hot-removed memory from the crash memory ranges in +remove_mem_range(), if the removed memory lies within an existing crash +range, that range is split into two. During this split, the size of the +second range was being calculated incorrectly. + +This leads to dump capture failure with makedumpfile with below error: + +$ makedumpfile -l -d 31 /proc/vmcore /tmp/vmcore + +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:16 +validate_mem_section: Can't read mem_section array. +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:8 +get_mm_sparsemem: Can't get the address of mem_section. + +The updated crash memory range in PT_LOAD entry is holding incorrect +data (checkout FileSiz and MemSiz): + +readelf -a /proc/vmcore + + Type Offset VirtAddr PhysAddr + FileSiz MemSiz Flags Align + LOAD 0x0000000b013d0000 0xc000000b80000000 0x0000000b80000000 + 0xffffffffc0000000 0xffffffffc0000000 RWE 0x0 + + +Update the size calculation for the new crash memory range to fix this +issue. + +Note: This problem will not occur if the kdump kernel is loaded or +reloaded after a memory hot-remove operation. + +Fixes: 849599b702ef ("powerpc/crash: add crash memory hotplug support") +Reported-by: Shirisha G +Signed-off-by: Sourabh Jain +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20251105033941.1752287-1-sourabhjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kexec/ranges.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c +index 3702b0bdab141..426bdca4667e7 100644 +--- a/arch/powerpc/kexec/ranges.c ++++ b/arch/powerpc/kexec/ranges.c +@@ -697,8 +697,8 @@ int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size) + * two half. + */ + else { ++ size = mem_rngs->ranges[i].end - end + 1; + mem_rngs->ranges[i].end = base - 1; +- size = mem_rngs->ranges[i].end - end; + ret = add_mem_range(mem_ranges, end + 1, size); + } + } +-- +2.51.0 + diff --git a/queue-6.12/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-6.12/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..7166d7cc5e --- /dev/null +++ b/queue-6.12/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From 5d667f44478b32f4050a597d4500efb86cd933bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index 226ffc743238e..b5b00021fe37d 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-6.12/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-6.12/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..5542be7a10 --- /dev/null +++ b/queue-6.12/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From 068d385f39bea9ba5d3dc582ad15b13f601c477a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 578e95e0296c6..532903da521fd 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -34,29 +34,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return pwmchip_get_drvdata(chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -102,6 +79,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -119,8 +99,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + }; + +-- +2.51.0 + diff --git a/queue-6.12/ras-report-all-arm-processor-cper-information-to-use.patch b/queue-6.12/ras-report-all-arm-processor-cper-information-to-use.patch new file mode 100644 index 0000000000..13f5626fe7 --- /dev/null +++ b/queue-6.12/ras-report-all-arm-processor-cper-information-to-use.patch @@ -0,0 +1,308 @@ +From 6e0bf7ae032fdb6ab3e7109b34aa168a9d2ad9fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 09:52:52 -0700 +Subject: RAS: Report all ARM processor CPER information to userspace + +From: Jason Tian + +[ Upstream commit 05954511b73e748d0370549ad9dd9cd95297d97a ] + +The ARM processor CPER record was added in UEFI v2.6 and remained +unchanged up to v2.10. + +Yet, the original arm_event trace code added by + + e9279e83ad1f ("trace, ras: add ARM processor error trace event") + +is incomplete, as it only traces some fields of UAPI 2.6 table N.16, not +exporting any information from tables N.17 to N.29 of the record. + +This is not enough for the user to be able to figure out what has +exactly happened or to take appropriate action. + +According to the UEFI v2.9 specification chapter N2.4.4, the ARM +processor error section includes: + +- several (ERR_INFO_NUM) ARM processor error information structures + (Tables N.17 to N.20); +- several (CONTEXT_INFO_NUM) ARM processor context information + structures (Tables N.21 to N.29); +- several vendor specific error information structures. The + size is given by Section Length minus the size of the other + fields. + +In addition, it also exports two fields that are parsed by the GHES +driver when firmware reports it, e.g.: + +- error severity +- CPU logical index + +Report all of these information to userspace via a the ARM tracepoint so +that userspace can properly record the error and take decisions related +to CPU core isolation according to error severity and other info. + +The updated ARM trace event now contains the following fields: + +====================================== ============================= +UEFI field on table N.16 ARM Processor trace fields +====================================== ============================= +Validation handled when filling data for + affinity MPIDR and running + state. +ERR_INFO_NUM pei_len +CONTEXT_INFO_NUM ctx_len +Section Length indirectly reported by + pei_len, ctx_len and oem_len +Error affinity level affinity +MPIDR_EL1 mpidr +MIDR_EL1 midr +Running State running_state +PSCI State psci_state +Processor Error Information Structure pei_err - count at pei_len +Processor Context ctx_err- count at ctx_len +Vendor Specific Error Info oem - count at oem_len +====================================== ============================= + +It should be noted that decoding of tables N.17 to N.29, if needed, will +be handled in userspace. That gives more flexibility, as there won't be +any need to flood the kernel with micro-architecture specific error +decoding. + +Also, decoding the other fields require a complex logic, and should be +done for each of the several values inside the record field. So, let +userspace daemons like rasdaemon decode them, parsing such tables and +having vendor-specific micro-architecture-specific decoders. + + [mchehab: modified description, solved merge conflicts and fixed coding style] + +Signed-off-by: Jason Tian +Co-developed-by: Shengwei Luo +Signed-off-by: Shengwei Luo +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Daniel Ferguson # rebased +Reviewed-by: Jonathan Cameron +Tested-by: Shiju Jose +Acked-by: Borislav Petkov (AMD) +Fixes: e9279e83ad1f ("trace, ras: add ARM processor error trace event") +Link: https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#arm-processor-error-section +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/acpi/apei/ghes.c | 11 ++++----- + drivers/ras/ras.c | 40 ++++++++++++++++++++++++++++++-- + include/linux/ras.h | 16 ++++++++++--- + include/ras/ras_event.h | 49 ++++++++++++++++++++++++++++++++++++---- + 4 files changed, 99 insertions(+), 17 deletions(-) + +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index 91f9267c07ea2..99659478e0bd0 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -527,7 +527,7 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + } + + static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, +- int sev, bool sync) ++ int sev, bool sync) + { + struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); + int flags = sync ? MF_ACTION_REQUIRED : 0; +@@ -535,9 +535,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, + int sec_sev, i; + char *p; + +- log_arm_hw_error(err); +- + sec_sev = ghes_severity(gdata->error_severity); ++ log_arm_hw_error(err, sec_sev); + if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) + return false; + +@@ -771,11 +770,9 @@ static bool ghes_do_proc(struct ghes *ghes, + + arch_apei_report_mem_error(sev, mem_err); + queued = ghes_handle_memory_failure(gdata, sev, sync); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { + ghes_handle_aer(gdata); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { + queued = ghes_handle_arm_hw_error(gdata, sev, sync); + } else if (guid_equal(sec_type, &CPER_SEC_CXL_GEN_MEDIA_GUID)) { + struct cxl_cper_event_rec *rec = acpi_hest_get_payload(gdata); +diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c +index a6e4792a1b2e9..c1b36a5601c4b 100644 +--- a/drivers/ras/ras.c ++++ b/drivers/ras/ras.c +@@ -52,9 +52,45 @@ void log_non_standard_event(const guid_t *sec_type, const guid_t *fru_id, + trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len); + } + +-void log_arm_hw_error(struct cper_sec_proc_arm *err) ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) + { +- trace_arm_event(err); ++ struct cper_arm_err_info *err_info; ++ struct cper_arm_ctx_info *ctx_info; ++ u8 *ven_err_data; ++ u32 ctx_len = 0; ++ int n, sz, cpu; ++ s32 vsei_len; ++ u32 pei_len; ++ u8 *pei_err, *ctx_err; ++ ++ pei_len = sizeof(struct cper_arm_err_info) * err->err_info_num; ++ pei_err = (u8 *)(err + 1); ++ ++ err_info = (struct cper_arm_err_info *)(err + 1); ++ ctx_info = (struct cper_arm_ctx_info *)(err_info + err->err_info_num); ++ ctx_err = (u8 *)ctx_info; ++ ++ for (n = 0; n < err->context_info_num; n++) { ++ sz = sizeof(struct cper_arm_ctx_info) + ctx_info->size; ++ ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + sz); ++ ctx_len += sz; ++ } ++ ++ vsei_len = err->section_length - (sizeof(struct cper_sec_proc_arm) + pei_len + ctx_len); ++ if (vsei_len < 0) { ++ pr_warn(FW_BUG "section length: %d\n", err->section_length); ++ pr_warn(FW_BUG "section length is too small\n"); ++ pr_warn(FW_BUG "firmware-generated error record is incorrect\n"); ++ vsei_len = 0; ++ } ++ ven_err_data = (u8 *)ctx_info; ++ ++ cpu = GET_LOGICAL_INDEX(err->mpidr); ++ if (cpu < 0) ++ cpu = -1; ++ ++ trace_arm_event(err, pei_err, pei_len, ctx_err, ctx_len, ++ ven_err_data, (u32)vsei_len, sev, cpu); + } + + static int __init ras_init(void) +diff --git a/include/linux/ras.h b/include/linux/ras.h +index a64182bc72ad3..468941bfe855f 100644 +--- a/include/linux/ras.h ++++ b/include/linux/ras.h +@@ -24,8 +24,7 @@ int __init parse_cec_param(char *str); + void log_non_standard_event(const guid_t *sec_type, + const guid_t *fru_id, const char *fru_text, + const u8 sev, const u8 *err, const u32 len); +-void log_arm_hw_error(struct cper_sec_proc_arm *err); +- ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev); + #else + static inline void + log_non_standard_event(const guid_t *sec_type, +@@ -33,7 +32,7 @@ log_non_standard_event(const guid_t *sec_type, + const u8 sev, const u8 *err, const u32 len) + { return; } + static inline void +-log_arm_hw_error(struct cper_sec_proc_arm *err) { return; } ++log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; } + #endif + + struct atl_err { +@@ -53,4 +52,15 @@ static inline unsigned long + amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; } + #endif /* CONFIG_AMD_ATL */ + ++#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) ++#include ++/* ++ * Include ARM-specific SMP header which provides a function mapping mpidr to ++ * CPU logical index. ++ */ ++#define GET_LOGICAL_INDEX(mpidr) get_logical_index(mpidr & MPIDR_HWID_BITMASK) ++#else ++#define GET_LOGICAL_INDEX(mpidr) -EINVAL ++#endif /* CONFIG_ARM || CONFIG_ARM64 */ ++ + #endif /* __RAS_H__ */ +diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h +index e5f7ee0864e78..7c8d3477305d1 100644 +--- a/include/ras/ras_event.h ++++ b/include/ras/ras_event.h +@@ -168,11 +168,25 @@ TRACE_EVENT(mc_event, + * This event is generated when hardware detects an ARM processor error + * has occurred. UEFI 2.6 spec section N.2.4.4. + */ ++#define APEIL "ARM Processor Err Info data len" ++#define APEID "ARM Processor Err Info raw data" ++#define APECIL "ARM Processor Err Context Info data len" ++#define APECID "ARM Processor Err Context Info raw data" ++#define VSEIL "Vendor Specific Err Info data len" ++#define VSEID "Vendor Specific Err Info raw data" + TRACE_EVENT(arm_event, + +- TP_PROTO(const struct cper_sec_proc_arm *proc), ++ TP_PROTO(const struct cper_sec_proc_arm *proc, ++ const u8 *pei_err, ++ const u32 pei_len, ++ const u8 *ctx_err, ++ const u32 ctx_len, ++ const u8 *oem, ++ const u32 oem_len, ++ u8 sev, ++ int cpu), + +- TP_ARGS(proc), ++ TP_ARGS(proc, pei_err, pei_len, ctx_err, ctx_len, oem, oem_len, sev, cpu), + + TP_STRUCT__entry( + __field(u64, mpidr) +@@ -180,6 +194,14 @@ TRACE_EVENT(arm_event, + __field(u32, running_state) + __field(u32, psci_state) + __field(u8, affinity) ++ __field(u32, pei_len) ++ __dynamic_array(u8, pei_buf, pei_len) ++ __field(u32, ctx_len) ++ __dynamic_array(u8, ctx_buf, ctx_len) ++ __field(u32, oem_len) ++ __dynamic_array(u8, oem_buf, oem_len) ++ __field(u8, sev) ++ __field(int, cpu) + ), + + TP_fast_assign( +@@ -199,12 +221,29 @@ TRACE_EVENT(arm_event, + __entry->running_state = ~0; + __entry->psci_state = ~0; + } ++ __entry->pei_len = pei_len; ++ memcpy(__get_dynamic_array(pei_buf), pei_err, pei_len); ++ __entry->ctx_len = ctx_len; ++ memcpy(__get_dynamic_array(ctx_buf), ctx_err, ctx_len); ++ __entry->oem_len = oem_len; ++ memcpy(__get_dynamic_array(oem_buf), oem, oem_len); ++ __entry->sev = sev; ++ __entry->cpu = cpu; + ), + +- TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " +- "running state: %d; PSCI state: %d", ++ TP_printk("cpu: %d; error: %d; affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " ++ "running state: %d; PSCI state: %d; " ++ "%s: %d; %s: %s; %s: %d; %s: %s; %s: %d; %s: %s", ++ __entry->cpu, ++ __entry->sev, + __entry->affinity, __entry->mpidr, __entry->midr, +- __entry->running_state, __entry->psci_state) ++ __entry->running_state, __entry->psci_state, ++ APEIL, __entry->pei_len, APEID, ++ __print_hex(__get_dynamic_array(pei_buf), __entry->pei_len), ++ APECIL, __entry->ctx_len, APECID, ++ __print_hex(__get_dynamic_array(ctx_buf), __entry->ctx_len), ++ VSEIL, __entry->oem_len, VSEID, ++ __print_hex(__get_dynamic_array(oem_buf), __entry->oem_len)) + ); + + /* +-- +2.51.0 + diff --git a/queue-6.12/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-6.12/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..4823b6a882 --- /dev/null +++ b/queue-6.12/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From 03a6e16e87e703f793ea6f423e4d9dc6c7ab5c29 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index 89186c499dd47..c26cb83ca0711 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-6.12/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch b/queue-6.12/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch new file mode 100644 index 0000000000..847d58407e --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch @@ -0,0 +1,40 @@ +From c0b39f96363b82a736d2eadd8d633d0cde03ab05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:54 -0800 +Subject: RDMA/bnxt_re: Fix the inline size for GenP7 devices + +From: Selvin Xavier + +[ Upstream commit 6afe40ff484a1155b71158b911c65299496e35c3 ] + +Inline size supported by the device is based on the number +of SGEs supported by the adapter. Change the inline +size calculation based on that. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kashyap Desai +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 807439b1acb51..59093d78062d3 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -161,7 +161,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw) + attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1; + attr->max_srq_sges = sb->max_srq_sge; + attr->max_pkey = 1; +- attr->max_inline_data = le32_to_cpu(sb->max_inline_data); ++ attr->max_inline_data = attr->max_qp_sges * sizeof(struct sq_sge); + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) + attr->l2_db_size = (sb->l2_db_space_size + 1) * + (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); +-- +2.51.0 + diff --git a/queue-6.12/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch b/queue-6.12/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch new file mode 100644 index 0000000000..1d7c6213f4 --- /dev/null +++ b/queue-6.12/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch @@ -0,0 +1,109 @@ +From fcfa8ec47b72fc295474310f1b32f071e0c4b6a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:55 -0800 +Subject: RDMA/bnxt_re: Pass correct flag for dma mr creation + +From: Selvin Xavier + +[ Upstream commit a26c4c7cdb50247b8486f1caa1ea8ab5e5c37edf ] + +DMA MR doesn't use the unified MR model. So the lkey passed +on to the reg_mr command to FW should contain the correct +lkey. Driver is incorrectly over writing the lkey with pdid +and firmware commands fails due to this. + +Avoid passing the wrong key for cases where the unified MR +registration is not used. + +Fixes: f786eebbbefa ("RDMA/bnxt_re: Avoid an extra hwrm per MR creation") +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-2-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 +++++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 6 +++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.h | 2 +- + 3 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index b222bf4f38e1c..c2abf2bb80264 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -541,7 +541,8 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd) + mr->qplib_mr.va = (u64)(unsigned long)fence->va; + mr->qplib_mr.total_size = BNXT_RE_FENCE_BYTES; + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, +- BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE); ++ BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register fence-MR\n"); + goto fail; +@@ -3916,7 +3917,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *ib_pd, int mr_access_flags) + mr->qplib_mr.hwq.level = PBL_LVL_MAX; + mr->qplib_mr.total_size = -1; /* Infinte length */ + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, 0, +- PAGE_SIZE); ++ PAGE_SIZE, false); + if (rc) + goto fail_mr; + +@@ -4146,7 +4147,8 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64 + + umem_pgs = ib_umem_num_dma_blocks(umem, page_size); + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, umem, +- umem_pgs, page_size); ++ umem_pgs, page_size, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register user MR - rc = %d\n", rc); + rc = -EIO; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 59093d78062d3..b09ac66e64466 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -612,7 +612,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + } + + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size) ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; + struct bnxt_qplib_hwq_attr hwq_attr = {}; +@@ -674,7 +674,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + req.access = (mr->access_flags & 0xFFFF); + req.va = cpu_to_le64(mr->va); + req.key = cpu_to_le32(mr->lkey); +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) ++ if (unified_mr) + req.key = cpu_to_le32(mr->pd->id); + req.flags = cpu_to_le16(mr->flags); + req.mr_size = cpu_to_le64(mr->total_size); +@@ -685,7 +685,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + if (rc) + goto fail; + +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) { ++ if (unified_mr) { + mr->lkey = le32_to_cpu(resp.xid); + mr->rkey = mr->lkey; + } +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +index de959b3c28e01..fcfef5cbb38d4 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +@@ -338,7 +338,7 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, + int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + bool block); + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size); ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr); + int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr); + int bnxt_qplib_alloc_fast_reg_mr(struct bnxt_qplib_res *res, + struct bnxt_qplib_mrw *mr, int max); +-- +2.51.0 + diff --git a/queue-6.12/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch b/queue-6.12/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch new file mode 100644 index 0000000000..5891d0060b --- /dev/null +++ b/queue-6.12/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch @@ -0,0 +1,166 @@ +From 7b3ce7a3842717372ac363a3812793b444d328fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:47 -0600 +Subject: RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY + +From: Jacob Moroni + +[ Upstream commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f ] + +The HW disables bounds checking for MRs with a length of zero, so +the driver will only allow a zero length MR if the "all_memory" +flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY +is set for the PD. + +This means that the "get_dma_mr" method will currently fail unless +the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue +because the "get_dma_mr" method is only ever invoked if the device +does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY +is set, and so far, all IRDMA HW supports the local DMA lkey. + +However, some new HW does not support the local DMA lkey, so the +"get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY +being set. + +To support HW that does not allow the local DMA lkey, the logic has +been changed to pass an explicit flag to indicate when a dma_mr is +being created so that the zero length will be allowed. + +Also, the "all_memory" flag has been forced to false for normal MR +allocation since these MRs are never supposed to provide global +unsafe rkey semantics anyway; only the MR created with "get_dma_mr" +should support this. + +Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/cm.c | 2 +- + drivers/infiniband/hw/irdma/main.h | 2 +- + drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- + drivers/infiniband/hw/irdma/verbs.h | 3 ++- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c +index ce8d821bdad84..7b9cba80a7f74 100644 +--- a/drivers/infiniband/hw/irdma/cm.c ++++ b/drivers/infiniband/hw/irdma/cm.c +@@ -3709,7 +3709,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + iwpd = iwqp->iwpd; + tagged_offset = (uintptr_t)iwqp->ietf_mem.va; + ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, +- IB_ACCESS_LOCAL_WRITE, &tagged_offset); ++ IB_ACCESS_LOCAL_WRITE, &tagged_offset, false); + if (IS_ERR(ibmr)) { + ret = -ENOMEM; + goto error; +diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h +index 9f0ed6e844711..e8f5f8aaa5653 100644 +--- a/drivers/infiniband/hw/irdma/main.h ++++ b/drivers/infiniband/hw/irdma/main.h +@@ -535,7 +535,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src); + u16 irdma_get_vlan_ipv4(u32 *addr); + void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac); + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size, +- int acc, u64 *iova_start); ++ int acc, u64 *iova_start, bool dma_mr); + int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw); + void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq); + int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 63d07fcab6569..c33a36d5c43c1 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2654,7 +2654,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; + info->pd_id = iwpd->sc_pd.pd_id; + info->total_len = iwmr->len; +- info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; + info->remote_access = true; + cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; + cqp_info->post_sq = 1; +@@ -2665,7 +2664,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + if (status) + return status; + +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + return 0; + } + +@@ -2806,7 +2805,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + stag_info->total_len = iwmr->len; + stag_info->access_rights = irdma_get_mr_access(access); + stag_info->pd_id = iwpd->sc_pd.pd_id; +- stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; ++ stag_info->all_memory = iwmr->dma_mr; + if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) + stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; + else +@@ -2833,7 +2832,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + + if (!ret) +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + + return ret; + } +@@ -3160,7 +3159,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr) + if (status) + return status; + +- iwmr->is_hwreg = 0; ++ iwmr->is_hwreg = false; + return 0; + } + +@@ -3283,9 +3282,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, + * @size: size of memory to register + * @access: Access rights + * @iova_start: start of virtual address for physical buffers ++ * @dma_mr: Flag indicating whether this region is a PD DMA MR + */ + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access, +- u64 *iova_start) ++ u64 *iova_start, bool dma_mr) + { + struct irdma_device *iwdev = to_iwdev(pd->device); + struct irdma_pbl *iwpbl; +@@ -3302,6 +3302,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access + iwpbl = &iwmr->iwpbl; + iwpbl->iwmr = iwmr; + iwmr->type = IRDMA_MEMREG_TYPE_MEM; ++ iwmr->dma_mr = dma_mr; + iwpbl->user_base = *iova_start; + stag = irdma_create_stag(iwdev); + if (!stag) { +@@ -3340,7 +3341,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) + { + u64 kva = 0; + +- return irdma_reg_phys_mr(pd, 0, 0, acc, &kva); ++ return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true); + } + + /** +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index 36ff8dd712f00..cbd8bef68ae4f 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -101,7 +101,8 @@ struct irdma_mr { + }; + struct ib_umem *region; + int access; +- u8 is_hwreg; ++ bool is_hwreg:1; ++ bool dma_mr:1; + u16 type; + u32 page_cnt; + u64 page_size; +-- +2.51.0 + diff --git a/queue-6.12/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-6.12/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..573ba6ce96 --- /dev/null +++ b/queue-6.12/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From 4e6b4a3c77a3284dedb9dc2683f800b939772ed7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index f381b8d51f532..bd9e7b7f6ca34 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-6.12/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-6.12/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..b9e06a536c --- /dev/null +++ b/queue-6.12/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From 72d514c37d1d4b7a84e01d27eacc3c33a14a7d78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index 6aed6169c07d7..de1bd2b57414a 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3316,11 +3316,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3331,6 +3333,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-6.12/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-6.12/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..47b4ecf71d --- /dev/null +++ b/queue-6.12/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From 8a99847071b53bfceaa0de599ffcd0d44f14a307 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index ef4abdea3c2d2..9ecc6343455d6 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1450,7 +1450,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-6.12/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch b/queue-6.12/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch new file mode 100644 index 0000000000..5d0f9a7a6a --- /dev/null +++ b/queue-6.12/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch @@ -0,0 +1,94 @@ +From 90119f2048db234aae65dfce25e6994bb4ab8cbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:52:03 -0700 +Subject: RDMA/rxe: Fix null deref on srq->rq.queue after resize failure + +From: Zhu Yanjun + +[ Upstream commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 ] + +A NULL pointer dereference can occur in rxe_srq_chk_attr() when +ibv_modify_srq() is invoked twice in succession under certain error +conditions. The first call may fail in rxe_queue_resize(), which leads +rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then +triggers a crash (null deref) when accessing +srq->rq.queue->buf->index_mask. + +Call Trace: + +rxe_modify_srq+0x170/0x480 [rdma_rxe] +? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe] +? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs] +? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs] +ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs] +? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs] +? tryinc_node_nr_active+0xe6/0x150 +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs] +? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs] +? __pfx___raw_spin_lock_irqsave+0x10/0x10 +? __pfx_do_vfs_ioctl+0x10/0x10 +? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0 +? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10 +ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs] +? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs] +__x64_sys_ioctl+0x138/0x1c0 +do_syscall_64+0x82/0x250 +? fdget_pos+0x58/0x4c0 +? ksys_write+0xf3/0x1c0 +? __pfx_ksys_write+0x10/0x10 +? do_syscall_64+0xc8/0x250 +? __pfx_vm_mmap_pgoff+0x10/0x10 +? fget+0x173/0x230 +? fput+0x2a/0x80 +? ksys_mmap_pgoff+0x224/0x4c0 +? do_syscall_64+0xc8/0x250 +? do_user_addr_fault+0x37b/0xfe0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Tested-by: Liu Yi +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c +index 3661cb627d28a..2a234f26ac104 100644 +--- a/drivers/infiniband/sw/rxe/rxe_srq.c ++++ b/drivers/infiniband/sw/rxe/rxe_srq.c +@@ -171,7 +171,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + udata, mi, &srq->rq.producer_lock, + &srq->rq.consumer_lock); + if (err) +- goto err_free; ++ return err; + + srq->rq.max_wr = attr->max_wr; + } +@@ -180,11 +180,6 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + srq->limit = attr->srq_limit; + + return 0; +- +-err_free: +- rxe_queue_cleanup(q); +- srq->rq.queue = NULL; +- return err; + } + + void rxe_srq_cleanup(struct rxe_pool_elem *elem) +-- +2.51.0 + diff --git a/queue-6.12/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-6.12/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..e7614e4f7e --- /dev/null +++ b/queue-6.12/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From c7cd01c472fd0d945e90289dcd96f1304d002593 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index e7f2a8b659477..be9704d34c015 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1593,6 +1593,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1612,11 +1614,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-6.12/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..39adc527b7 --- /dev/null +++ b/queue-6.12/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 038fb8a8fff879e77472ee2ed89b31ea1e36d876 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index be9704d34c015..1c0748fee6846 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1914,6 +1914,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1922,6 +1923,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2442,22 +2444,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2477,11 +2483,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-6.12/reinstate-resource-avoid-unnecessary-lookups-in-find.patch b/queue-6.12/reinstate-resource-avoid-unnecessary-lookups-in-find.patch new file mode 100644 index 0000000000..76bc1b2002 --- /dev/null +++ b/queue-6.12/reinstate-resource-avoid-unnecessary-lookups-in-find.patch @@ -0,0 +1,85 @@ +From bf475abf04ee536a96fe23d94c67049fbf2df08c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:53:49 +0000 +Subject: Reinstate "resource: avoid unnecessary lookups in + find_next_iomem_res()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilias Stamatis + +[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ] + +Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only +logic") removed an optimization introduced by commit 756398750e11 +("resource: avoid unnecessary lookups in find_next_iomem_res()"). That +was not called out in the message of the first commit explicitly so it's +not entirely clear whether removing the optimization happened +inadvertently or not. + +As the original commit message of the optimization explains there is no +point considering the children of a subtree in find_next_iomem_res() if +the top level range does not match. + +Reinstating the optimization results in performance improvements in +systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem +in such platforms takes 700-1500μs without the optimisation and 10-50μs +with the optimisation. + +Note that even though commit 97523a4edb7b removed the 'sibling_only' +parameter from next_resource(), newer kernels have basically reinstated it +under the name 'skip_children'. + +Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u +Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") +Signed-off-by: Ilias Stamatis +Acked-by: David Hildenbrand (Red Hat) +Cc: Andriy Shevchenko +Cc: Baoquan He +Cc: "Huang, Ying" +Cc: Nadav Amit +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 03b6b8de58bfb..2182854dde68e 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -323,6 +323,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + unsigned long flags, unsigned long desc, + struct resource *res) + { ++ /* Skip children until we find a top level range that matches */ ++ bool skip_children = true; + struct resource *p; + + if (!res) +@@ -333,7 +335,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for_each_resource(&iomem_resource, p, false) { ++ for_each_resource(&iomem_resource, p, skip_children) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -344,6 +346,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + ++ /* ++ * We found a top level range that matches what we are looking ++ * for. Time to start checking children too. ++ */ ++ skip_children = false; ++ + /* Found a match, break */ + if (is_type_match(p, flags, desc)) + break; +-- +2.51.0 + diff --git a/queue-6.12/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-6.12/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..f0a1546561 --- /dev/null +++ b/queue-6.12/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From b89324d09f025f59d8ff6ad43a034508183a25d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index e913dabae9924..c560b81b72631 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.12/resource-introduce-is_type_match-helper-and-use-it.patch b/queue-6.12/resource-introduce-is_type_match-helper-and-use-it.patch new file mode 100644 index 0000000000..8442cacf3f --- /dev/null +++ b/queue-6.12/resource-introduce-is_type_match-helper-and-use-it.patch @@ -0,0 +1,91 @@ +From 7455cd72c556747a739e913373d4bf09cd43283b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:35 +0300 +Subject: resource: introduce is_type_match() helper and use it + +From: Andy Shevchenko + +[ Upstream commit ba1eccc114ffc62c4495a5e15659190fa2c42308 ] + +There are already a couple of places where we may replace a few lines of +code by calling a helper, which increases readability while deduplicating +the code. + +Introduce is_type_match() helper and use it. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index c3e00365f8e37..03b6b8de58bfb 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -297,6 +297,11 @@ int release_resource(struct resource *old) + + EXPORT_SYMBOL(release_resource); + ++static bool is_type_match(struct resource *p, unsigned long flags, unsigned long desc) ++{ ++ return (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc); ++} ++ + /** + * find_next_iomem_res - Finds the lowest iomem resource that covers part of + * [@start..@end]. +@@ -339,13 +344,9 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + +- if ((p->flags & flags) != flags) +- continue; +- if ((desc != IORES_DESC_NONE) && (desc != p->desc)) +- continue; +- + /* Found a match, break */ +- break; ++ if (is_type_match(p, flags, desc)) ++ break; + } + + if (p) { +@@ -540,7 +541,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + int type = 0; int other = 0; + struct resource *p, *dp; + struct resource res, o; +- bool is_type, covered; ++ bool covered; + + res.start = start; + res.end = start + size - 1; +@@ -548,9 +549,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for (p = parent->child; p ; p = p->sibling) { + if (!resource_intersection(p, &res, &o)) + continue; +- is_type = (p->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == p->desc); +- if (is_type) { ++ if (is_type_match(p, flags, desc)) { + type++; + continue; + } +@@ -570,9 +569,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +- is_type = (dp->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == dp->desc); +- if (is_type) { ++ if (is_type_match(dp, flags, desc)) { + type++; + /* + * Range from 'o.start' to 'dp->start' +-- +2.51.0 + diff --git a/queue-6.12/resource-replace-open-coded-resource_intersection.patch b/queue-6.12/resource-replace-open-coded-resource_intersection.patch new file mode 100644 index 0000000000..d1b7126558 --- /dev/null +++ b/queue-6.12/resource-replace-open-coded-resource_intersection.patch @@ -0,0 +1,88 @@ +From 5ba75cb9a6faec911ad43099204df6f649285900 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:34 +0300 +Subject: resource: replace open coded resource_intersection() + +From: Andy Shevchenko + +[ Upstream commit 5c1edea773c98707fbb23d1df168bcff52f61e4b ] + +Patch series "resource: A couple of cleanups". + +A couple of ad-hoc cleanups since there was a recent development of +the code in question. No functional changes intended. + +This patch (of 2): + +__region_intersects() uses open coded resource_intersection(). Replace it +with existing API which also make more clear what we are checking. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-1-andriy.shevchenko@linux.intel.com +Link: https://lkml.kernel.org/r/20240925154355.1170859-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 1d48ae8646352..c3e00365f8e37 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -537,17 +537,16 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + size_t size, unsigned long flags, + unsigned long desc) + { +- resource_size_t ostart, oend; + int type = 0; int other = 0; + struct resource *p, *dp; ++ struct resource res, o; + bool is_type, covered; +- struct resource res; + + res.start = start; + res.end = start + size - 1; + + for (p = parent->child; p ; p = p->sibling) { +- if (!resource_overlaps(p, &res)) ++ if (!resource_intersection(p, &res, &o)) + continue; + is_type = (p->flags & flags) == flags && + (desc == IORES_DESC_NONE || desc == p->desc); +@@ -568,8 +567,6 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + * |-- "System RAM" --||-- "CXL Window 0a" --| + */ + covered = false; +- ostart = max(res.start, p->start); +- oend = min(res.end, p->end); + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +@@ -578,17 +575,17 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + if (is_type) { + type++; + /* +- * Range from 'ostart' to 'dp->start' ++ * Range from 'o.start' to 'dp->start' + * isn't covered by matched resource. + */ +- if (dp->start > ostart) ++ if (dp->start > o.start) + break; +- if (dp->end >= oend) { ++ if (dp->end >= o.end) { + covered = true; + break; + } + /* Remove covered range */ +- ostart = max(ostart, dp->end + 1); ++ o.start = max(o.start, dp->end + 1); + } + } + if (!covered) +-- +2.51.0 + diff --git a/queue-6.12/revert-mtd-rawnand-marvell-fix-layouts.patch b/queue-6.12/revert-mtd-rawnand-marvell-fix-layouts.patch new file mode 100644 index 0000000000..df76df1752 --- /dev/null +++ b/queue-6.12/revert-mtd-rawnand-marvell-fix-layouts.patch @@ -0,0 +1,51 @@ +From 9ca0201f4801815f38c5d851896d0ef6b6fb1097 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:41 +1300 +Subject: Revert "mtd: rawnand: marvell: fix layouts" + +From: Aryan Srivastava + +[ Upstream commit fbd72cb463fdea3a0c900dd5d6e813cdebc3a73c ] + +This reverts commit e6a30d0c48a1e8a68f1cc413bee65302ab03ddfb. + +This change resulted in the 8bit ECC layouts having the incorrect amount +of read/write chunks, the last spare bytes chunk would always be missed. + +Fixes: e6a30d0c48a1 ("mtd: rawnand: marvell: fix layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index aa113a5d88c89..6613aaec581b9 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -290,13 +290,16 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { + MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,64, 30), +- MARVELL_LAYOUT( 2048, 512, 16, 4, 4, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 2048, 512, 12, 3, 2, 704, 0, 30,640, 0, 30), ++ MARVELL_LAYOUT( 2048, 512, 16, 5, 4, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), +- MARVELL_LAYOUT( 4096, 512, 8, 4, 4, 1024, 0, 30, 0, 64, 30), +- MARVELL_LAYOUT( 4096, 512, 16, 8, 8, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), ++ MARVELL_LAYOUT( 4096, 512, 12, 6, 5, 704, 0, 30,576, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 16, 9, 8, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 8192, 512, 4, 4, 4, 2048, 0, 30, 0, 0, 0), +- MARVELL_LAYOUT( 8192, 512, 8, 8, 8, 1024, 0, 30, 0, 160, 30), +- MARVELL_LAYOUT( 8192, 512, 16, 16, 16, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 8192, 512, 8, 9, 8, 1024, 0, 30, 0, 160, 30), ++ MARVELL_LAYOUT( 8192, 512, 12, 12, 11, 704, 0, 30,448, 64, 30), ++ MARVELL_LAYOUT( 8192, 512, 16, 17, 16, 512, 0, 30, 0, 32, 30), + }; + + /** +-- +2.51.0 + diff --git a/queue-6.12/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch b/queue-6.12/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch new file mode 100644 index 0000000000..80ae4765b2 --- /dev/null +++ b/queue-6.12/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch @@ -0,0 +1,84 @@ +From 5a51b090d817a171703a5901b555189d1338ed6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 21:35:43 +0800 +Subject: RISC-V: KVM: Fix guest page fault within HLV* instructions + +From: Fangyu Yu + +[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ] + +When executing HLV* instructions at the HS mode, a guest page fault +may occur when a g-stage page table migration between triggering the +virtual instruction exception and executing the HLV* instruction. + +This may be a corner case, and one simpler way to handle this is to +re-execute the instruction where the virtual instruction exception +occurred, and the guest page fault will be automatically handled. + +Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") +Signed-off-by: Fangyu Yu +Reviewed-by: Anup Patel +Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index 97dec18e69892..3dbd6a09d4825 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -424,6 +424,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + return (rc <= 0) ? rc : 1; + } + ++static bool is_load_guest_page_fault(unsigned long scause) ++{ ++ /** ++ * If a g-stage page fault occurs, the direct approach ++ * is to let the g-stage page fault handler handle it ++ * naturally, however, calling the g-stage page fault ++ * handler here seems rather strange. ++ * Considering this is a corner case, we can directly ++ * return to the guest and re-execute the same PC, this ++ * will trigger a g-stage page fault again and then the ++ * regular g-stage page fault handler will populate ++ * g-stage page table. ++ */ ++ return (scause == EXC_LOAD_GUEST_PAGE_FAULT); ++} ++ + /** + * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap + * +@@ -449,6 +465,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + return 1; +@@ -504,6 +522,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +@@ -630,6 +650,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +-- +2.51.0 + diff --git a/queue-6.12/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-6.12/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..6669d32748 --- /dev/null +++ b/queue-6.12/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From 4067edb88c317737e25a8696e483c713879c6e8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index e14638936de6b..e7068016a9868 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -2419,15 +2419,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-6.12/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch b/queue-6.12/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch new file mode 100644 index 0000000000..23fbc37199 --- /dev/null +++ b/queue-6.12/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch @@ -0,0 +1,160 @@ +From f80770b225e9d80a0d90eda2942adfce2f69e5b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 16:59:16 +0100 +Subject: s390/fpu: Fix false-positive kmsan report in fpu_vstl() + +From: Aleksei Nikiforov + +[ Upstream commit 14e4e4175b64dd9216b522f6ece8af6997d063b2 ] + +A false-positive kmsan report is detected when running ping command. + +An inline assembly instruction 'vstl' can write varied amount of bytes +depending on value of 'index' argument. If 'index' > 0, 'vstl' writes +at least 2 bytes. + +clang generates kmsan write helper call depending on inline assembly +constraints. Constraints are evaluated compile-time, but value of +'index' argument is known only at runtime. + +clang currently generates call to __msan_instrument_asm_store with 1 byte +as size. Manually call kmsan function to indicate correct amount of bytes +written and fix false-positive report. + +This change fixes following kmsan reports: + +[ 36.563119] ===================================================== +[ 36.563594] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 36.563852] virtqueue_add+0x35c6/0x7c70 +[ 36.564016] virtqueue_add_outbuf+0xa0/0xb0 +[ 36.564266] start_xmit+0x288c/0x4a20 +[ 36.564460] dev_hard_start_xmit+0x302/0x900 +[ 36.564649] sch_direct_xmit+0x340/0xea0 +[ 36.564894] __dev_queue_xmit+0x2e94/0x59b0 +[ 36.565058] neigh_resolve_output+0x936/0xb40 +[ 36.565278] __neigh_update+0x2f66/0x3a60 +[ 36.565499] neigh_update+0x52/0x60 +[ 36.565683] arp_process+0x1588/0x2de0 +[ 36.565916] NF_HOOK+0x1da/0x240 +[ 36.566087] arp_rcv+0x3e4/0x6e0 +[ 36.566306] __netif_receive_skb_list_core+0x1374/0x15a0 +[ 36.566527] netif_receive_skb_list_internal+0x1116/0x17d0 +[ 36.566710] napi_complete_done+0x376/0x740 +[ 36.566918] virtnet_poll+0x1bae/0x2910 +[ 36.567130] __napi_poll+0xf4/0x830 +[ 36.567294] net_rx_action+0x97c/0x1ed0 +[ 36.567556] handle_softirqs+0x306/0xe10 +[ 36.567731] irq_exit_rcu+0x14c/0x2e0 +[ 36.567910] do_io_irq+0xd4/0x120 +[ 36.568139] io_int_handler+0xc2/0xe8 +[ 36.568299] arch_cpu_idle+0xb0/0xc0 +[ 36.568540] arch_cpu_idle+0x76/0xc0 +[ 36.568726] default_idle_call+0x40/0x70 +[ 36.568953] do_idle+0x1d6/0x390 +[ 36.569486] cpu_startup_entry+0x9a/0xb0 +[ 36.569745] rest_init+0x1ea/0x290 +[ 36.570029] start_kernel+0x95e/0xb90 +[ 36.570348] startup_continue+0x2e/0x40 +[ 36.570703] +[ 36.570798] Uninit was created at: +[ 36.571002] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 36.571261] kmalloc_reserve+0x12a/0x470 +[ 36.571553] __alloc_skb+0x310/0x860 +[ 36.571844] __ip_append_data+0x483e/0x6a30 +[ 36.572170] ip_append_data+0x11c/0x1e0 +[ 36.572477] raw_sendmsg+0x1c8c/0x2180 +[ 36.572818] inet_sendmsg+0xe6/0x190 +[ 36.573142] __sys_sendto+0x55e/0x8e0 +[ 36.573392] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 36.573571] __do_syscall+0x12e/0x240 +[ 36.573823] system_call+0x6e/0x90 +[ 36.573976] +[ 36.574017] Byte 35 of 98 is uninitialized +[ 36.574082] Memory access of size 98 starts at 0000000007aa0012 +[ 36.574218] +[ 36.574325] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G B N 6.17.0-dirty #16 NONE +[ 36.574541] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 36.574617] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 36.574755] ===================================================== + +[ 63.532541] ===================================================== +[ 63.533639] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 63.533989] virtqueue_add+0x35c6/0x7c70 +[ 63.534940] virtqueue_add_outbuf+0xa0/0xb0 +[ 63.535861] start_xmit+0x288c/0x4a20 +[ 63.536708] dev_hard_start_xmit+0x302/0x900 +[ 63.537020] sch_direct_xmit+0x340/0xea0 +[ 63.537997] __dev_queue_xmit+0x2e94/0x59b0 +[ 63.538819] neigh_resolve_output+0x936/0xb40 +[ 63.539793] ip_finish_output2+0x1ee2/0x2200 +[ 63.540784] __ip_finish_output+0x272/0x7a0 +[ 63.541765] ip_finish_output+0x4e/0x5e0 +[ 63.542791] ip_output+0x166/0x410 +[ 63.543771] ip_push_pending_frames+0x1a2/0x470 +[ 63.544753] raw_sendmsg+0x1f06/0x2180 +[ 63.545033] inet_sendmsg+0xe6/0x190 +[ 63.546006] __sys_sendto+0x55e/0x8e0 +[ 63.546859] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.547730] __do_syscall+0x12e/0x240 +[ 63.548019] system_call+0x6e/0x90 +[ 63.548989] +[ 63.549779] Uninit was created at: +[ 63.550691] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 63.550975] kmalloc_reserve+0x12a/0x470 +[ 63.551969] __alloc_skb+0x310/0x860 +[ 63.552949] __ip_append_data+0x483e/0x6a30 +[ 63.553902] ip_append_data+0x11c/0x1e0 +[ 63.554912] raw_sendmsg+0x1c8c/0x2180 +[ 63.556719] inet_sendmsg+0xe6/0x190 +[ 63.557534] __sys_sendto+0x55e/0x8e0 +[ 63.557875] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.558869] __do_syscall+0x12e/0x240 +[ 63.559832] system_call+0x6e/0x90 +[ 63.560780] +[ 63.560972] Byte 35 of 98 is uninitialized +[ 63.561741] Memory access of size 98 starts at 0000000005704312 +[ 63.561950] +[ 63.562824] CPU: 3 UID: 0 PID: 192 Comm: ping Tainted: G B N 6.17.0-dirty #16 NONE +[ 63.563868] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 63.564751] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 63.564986] ===================================================== + +Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()") +Signed-off-by: Aleksei Nikiforov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/fpu-insn.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h +index a4c9b4db62ff5..c74c6056087fe 100644 +--- a/arch/s390/include/asm/fpu-insn.h ++++ b/arch/s390/include/asm/fpu-insn.h +@@ -12,6 +12,7 @@ + #ifndef __ASSEMBLY__ + + #include ++#include + #include + + asm(".include \"asm/fpu-insn-asm.h\"\n"); +@@ -377,6 +378,7 @@ static __always_inline void fpu_vst(u8 v1, const void *vxr) + : [vxr] "=Q" (*(__vector128 *)vxr) + : [v1] "I" (v1) + : "memory"); ++ kmsan_unpoison_memory(vxr, size); + } + + #endif /* CONFIG_CC_IS_CLANG */ +@@ -395,6 +397,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) + : [vxr] "=R" (*(u8 *)vxr) + : [index] "d" (index), [v1] "I" (v1) + : "memory", "1"); ++ kmsan_unpoison_memory(vxr, size); + } + + #else /* CONFIG_CC_IS_CLANG */ +-- +2.51.0 + diff --git a/queue-6.12/s390-smp-fix-fallback-cpu-detection.patch b/queue-6.12/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..034c57cffd --- /dev/null +++ b/queue-6.12/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From 0167c9272ab5952258b3470ed9f127ee3aa08f06 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index 4df56fdb24880..b976f603dddcd 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -710,6 +710,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-6.12/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch b/queue-6.12/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch new file mode 100644 index 0000000000..a2361bc669 --- /dev/null +++ b/queue-6.12/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch @@ -0,0 +1,57 @@ +From a86b7e10cbb98378003b2b2d5501203244aa55e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Aug 2025 10:22:07 +0800 +Subject: sched/fair: Fix unfairness caused by stalled tg_load_avg_contrib when + the last task migrates out + +From: xupengbo + +[ Upstream commit ca125231dd29fc0678dd3622e9cdea80a51dffe4 ] + +When a task is migrated out, there is a probability that the tg->load_avg +value will become abnormal. The reason is as follows: + +1. Due to the 1ms update period limitation in update_tg_load_avg(), there + is a possibility that the reduced load_avg is not updated to tg->load_avg + when a task migrates out. + +2. Even though __update_blocked_fair() traverses the leaf_cfs_rq_list and + calls update_tg_load_avg() for cfs_rqs that are not fully decayed, the key + function cfs_rq_is_decayed() does not check whether + cfs->tg_load_avg_contrib is null. Consequently, in some cases, + __update_blocked_fair() removes cfs_rqs whose avg.load_avg has not been + updated to tg->load_avg. + +Add a check of cfs_rq->tg_load_avg_contrib in cfs_rq_is_decayed(), +which fixes the case (2.) mentioned above. + +Fixes: 1528c661c24b ("sched/fair: Ratelimit update to tg->load_avg") +Signed-off-by: xupengbo +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Reviewed-by: Aaron Lu +Reviewed-by: Vincent Guittot +Tested-by: Aaron Lu +Link: https://patch.msgid.link/20250827022208.14487-1-xupengbo@oppo.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index bf35f6f0a9c4b..62b8c7e914ebc 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4198,6 +4198,9 @@ static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) + if (child_cfs_rq_on_list(cfs_rq)) + return false; + ++ if (cfs_rq->tg_load_avg_contrib) ++ return false; ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.12/sched-fair-forfeit-vruntime-on-yield.patch b/queue-6.12/sched-fair-forfeit-vruntime-on-yield.patch new file mode 100644 index 0000000000..276004eb8e --- /dev/null +++ b/queue-6.12/sched-fair-forfeit-vruntime-on-yield.patch @@ -0,0 +1,68 @@ +From 5f046d12ecd340345d98fbc1cbd6370e4db9e3fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:05:28 +0200 +Subject: sched/fair: Forfeit vruntime on yield + +From: Fernand Sieber + +[ Upstream commit 79104becf42baeeb4a3f2b106f954b9fc7c10a3c ] + +If a task yields, the scheduler may decide to pick it again. The task in +turn may decide to yield immediately or shortly after, leading to a tight +loop of yields. + +If there's another runnable task as this point, the deadline will be +increased by the slice at each loop. This can cause the deadline to runaway +pretty quickly, and subsequent elevated run delays later on as the task +doesn't get picked again. The reason the scheduler can pick the same task +again and again despite its deadline increasing is because it may be the +only eligible task at that point. + +Fix this by making the task forfeiting its remaining vruntime and pushing +the deadline one slice ahead. This implements yield behavior more +authentically. + +We limit the forfeiting to eligible tasks. This is because core scheduling +prefers running ineligible tasks rather than force idling. As such, without +the condition, we can end up on a yield loop which makes the vruntime +increase rapidly, leading to anomalous run delays later down the line. + +Fixes: 147f3efaa24182 ("sched/fair: Implement an EEVDF-like scheduling policy") +Signed-off-by: Fernand Sieber +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20250401123622.584018-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250911095113.203439-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250916140228.452231-1-sieberf@amazon.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 8bdcb5df0d461..bf35f6f0a9c4b 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -9151,7 +9151,19 @@ static void yield_task_fair(struct rq *rq) + */ + rq_clock_skip_update(rq); + +- se->deadline += calc_delta_fair(se->slice, se); ++ /* ++ * Forfeit the remaining vruntime, only if the entity is eligible. This ++ * condition is necessary because in core scheduling we prefer to run ++ * ineligible tasks rather than force idling. If this happens we may ++ * end up in a loop where the core scheduler picks the yielding task, ++ * which yields immediately again; without the condition the vruntime ++ * ends up quickly running away. ++ */ ++ if (entity_eligible(cfs_rq, se)) { ++ se->vruntime = se->deadline; ++ se->deadline += calc_delta_fair(se->slice, se); ++ update_min_vruntime(cfs_rq); ++ } + } + + static bool yield_to_task_fair(struct rq *rq, struct task_struct *p) +-- +2.51.0 + diff --git a/queue-6.12/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch b/queue-6.12/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch new file mode 100644 index 0000000000..5a33746cb7 --- /dev/null +++ b/queue-6.12/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch @@ -0,0 +1,51 @@ +From b960d8913232792504fd63d33da25a7786c2eefd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 15:12:46 +0000 +Subject: scsi: qla2xxx: Fix improper freeing of purex item + +From: Zilin Guan + +[ Upstream commit 78b1a242fe612a755f2158fd206ee6bb577d18ca ] + +In qla2xxx_process_purls_iocb(), an item is allocated via +qla27xx_copy_multiple_pkt(), which internally calls +qla24xx_alloc_purex_item(). + +The qla24xx_alloc_purex_item() function may return a pre-allocated item +from a per-adapter pool for small allocations, instead of dynamically +allocating memory with kzalloc(). + +An error handling path in qla2xxx_process_purls_iocb() incorrectly uses +kfree() to release the item. If the item was from the pre-allocated +pool, calling kfree() on it is a bug that can lead to memory corruption. + +Fix this by using the correct deallocation function, +qla24xx_free_purex_item(), which properly handles both dynamically +allocated and pre-allocated items. + +Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") +Signed-off-by: Zilin Guan +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_nvme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 316594aa40cc5..42eb65a62f1f3 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) + a.reason = FCNVME_RJT_RC_LOGIC; + a.explanation = FCNVME_RJT_EXP_NONE; + xmt_reject = true; +- kfree(item); ++ qla24xx_free_purex_item(item); + goto out; + } + +-- +2.51.0 + diff --git a/queue-6.12/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-6.12/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..ed2c18cbfd --- /dev/null +++ b/queue-6.12/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From 2dfd17a42079446e5e70cfee381ee62e759b29a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-6.12/scsi-smartpqi-fix-device-resources-accessed-after-de.patch b/queue-6.12/scsi-smartpqi-fix-device-resources-accessed-after-de.patch new file mode 100644 index 0000000000..7bbd5d9bbe --- /dev/null +++ b/queue-6.12/scsi-smartpqi-fix-device-resources-accessed-after-de.patch @@ -0,0 +1,94 @@ +From 48f4a236b8258ff684c53e08ae483a923ca4d3e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 10:38:20 -0600 +Subject: scsi: smartpqi: Fix device resources accessed after device removal + +From: Mike McGowen + +[ Upstream commit b518e86d1a70a88f6592a7c396cf1b93493d1aab ] + +Correct possible race conditions during device removal. + +Previously, a scheduled work item to reset a LUN could still execute +after the device was removed, leading to use-after-free and other +resource access issues. + +This race condition occurs because the abort handler may schedule a LUN +reset concurrently with device removal via sdev_destroy(), leading to +use-after-free and improper access to freed resources. + + - Check in the device reset handler if the device is still present in + the controller's SCSI device list before running; if not, the reset + is skipped. + + - Cancel any pending TMF work that has not started in sdev_destroy(). + + - Ensure device freeing in sdev_destroy() is done while holding the + LUN reset mutex to avoid races with ongoing resets. + +Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index c5a21e369e167..018f5428a07d2 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6395,10 +6395,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev + + static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { ++ unsigned long flags; + int rc; + + mutex_lock(&ctrl_info->lun_reset_mutex); + ++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); ++ if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { ++ dev_warn(&ctrl_info->pci_dev->dev, ++ "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%u SCSI cmd at %p due to cmd opcode 0x%02x\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, lun, scmd, scsi_opcode); +@@ -6578,7 +6590,9 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + { + struct pqi_ctrl_info *ctrl_info; + struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; + int mutex_acquired; ++ unsigned int lun; + unsigned long flags; + + ctrl_info = shost_to_hba(sdev->host); +@@ -6605,8 +6619,13 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + + mutex_unlock(&ctrl_info->scan_mutex); + ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ cancel_work_sync(&tmf_work->work_struct); ++ ++ mutex_lock(&ctrl_info->lun_reset_mutex); + pqi_dev_info(ctrl_info, "removed", device); + pqi_free_device(device); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); + } + + static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) +-- +2.51.0 + diff --git a/queue-6.12/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-6.12/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..3aee29ebfb --- /dev/null +++ b/queue-6.12/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From 12456405eefc25869c807a27fa383d0de200ca80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index 0e81125df8c72..7af0341a99d2e 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1844,6 +1844,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-6.12/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-6.12/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..169b86b0e4 --- /dev/null +++ b/queue-6.12/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From f20f0fc993fa737eef72db773b0c832b9244d2c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index 3188bca17e1b9..68b40e01d5a09 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2774,7 +2774,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-6.12/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch b/queue-6.12/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch new file mode 100644 index 0000000000..fb46c47670 --- /dev/null +++ b/queue-6.12/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch @@ -0,0 +1,46 @@ +From 913234bc2caf98b6edeadfec7372a0e0f668febc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 00:05:17 +0100 +Subject: scsi: ufs: core: fix incorrect buffer duplication in + ufshcd_read_string_desc() + +From: Bean Huo + +[ Upstream commit d794b499f948801f54d67ddbc34a6eac5a6d150a ] + +The function ufshcd_read_string_desc() was duplicating memory starting +from the beginning of struct uc_string_id, which included the length and +type fields. As a result, the allocated buffer contained unwanted +metadata in addition to the string itself. + +The correct behavior is to duplicate only the Unicode character array in +the structure. Update the code so that only the actual string content is +copied into the new buffer. + +Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Bean Huo +Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index c8c22b95c3eef..33534e455b55c 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3799,7 +3799,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + str[ret++] = '\0'; + + } else { +- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); ++ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + goto out; +-- +2.51.0 + diff --git a/queue-6.12/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-6.12/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..85cdf83fe8 --- /dev/null +++ b/queue-6.12/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From 57f94693d905333b5ade1cadac694acc876cec21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index b301d64d9d80f..b6956b25b33d3 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1554,8 +1554,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5112,9 +5110,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Triggered when there are no references on the socket anymore */ +-- +2.51.0 + diff --git a/queue-6.12/selftests-bonding-add-delay-before-each-xvlan_over_b.patch b/queue-6.12/selftests-bonding-add-delay-before-each-xvlan_over_b.patch new file mode 100644 index 0000000000..ef635ef47b --- /dev/null +++ b/queue-6.12/selftests-bonding-add-delay-before-each-xvlan_over_b.patch @@ -0,0 +1,47 @@ +From 616fe22465ac6fdc8125aff9ea3f5b80cd95f82f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:33:10 +0000 +Subject: selftests: bonding: add delay before each xvlan_over_bond + connectivity check + +From: Hangbin Liu + +[ Upstream commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d ] + +Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular +kernel, while the tests consistently pass on a debug kernel. This suggests +a timing-sensitive issue. + +To mitigate this, introduce a short sleep before each xvlan_over_bond +connectivity check. The delay helps ensure neighbor and route cache +have fully converged before verifying connectivity. + +The sleep interval is kept minimal since check_connection() is invoked +nearly 100 times during the test. + +Fixes: 246af950b940 ("selftests: bonding: add macvlan over bond testing") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/netdev/20251114082014.750edfad@kernel.org +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251127143310.47740-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +index c4711272fe45d..559f300f965aa 100755 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -30,6 +30,7 @@ check_connection() + local message=${3} + RET=0 + ++ sleep 0.25 + ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null + check_err $? "ping failed" + log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" +-- +2.51.0 + diff --git a/queue-6.12/selftests-bonding-add-ipvlan-over-bond-testing.patch b/queue-6.12/selftests-bonding-add-ipvlan-over-bond-testing.patch new file mode 100644 index 0000000000..2027235895 --- /dev/null +++ b/queue-6.12/selftests-bonding-add-ipvlan-over-bond-testing.patch @@ -0,0 +1,275 @@ +From 1a3b98c5fbf68023448948a39ec6aefe5faaab98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 22:28:19 -0500 +Subject: selftests: bonding: add ipvlan over bond testing + +From: Etienne Champetier + +[ Upstream commit 08ac69b24507ab06871c18adc421c9d4f1008c61 ] + +This rework bond_macvlan.sh into bond_macvlan_ipvlan.sh +We only test bridge mode for macvlan and l2 mode + +]# ./bond_macvlan_ipvlan.sh +TEST: active-backup/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: active-backup/ipvlan_l2: IPv4: client->server [ OK ] +... +TEST: balance-tlb/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: balance-tlb/ipvlan_l2: IPv4: client->server [ OK ] +... +TEST: balance-alb/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: balance-alb/ipvlan_l2: IPv4: client->server [ OK ] +... + +Signed-off-by: Etienne Champetier +Link: https://patch.msgid.link/20250109032819.326528-3-champetier.etienne@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") +Signed-off-by: Sasha Levin +--- + .../selftests/drivers/net/bonding/Makefile | 2 +- + .../drivers/net/bonding/bond_macvlan.sh | 99 ------------------- + .../net/bonding/bond_macvlan_ipvlan.sh | 96 ++++++++++++++++++ + .../selftests/drivers/net/bonding/config | 1 + + 4 files changed, 98 insertions(+), 100 deletions(-) + delete mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh + create mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh + +diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile +index 03a089165d3fb..2b10854e4b1e3 100644 +--- a/tools/testing/selftests/drivers/net/bonding/Makefile ++++ b/tools/testing/selftests/drivers/net/bonding/Makefile +@@ -10,7 +10,7 @@ TEST_PROGS := \ + mode-2-recovery-updelay.sh \ + bond_options.sh \ + bond-eth-type-change.sh \ +- bond_macvlan.sh ++ bond_macvlan_ipvlan.sh + + TEST_FILES := \ + lag_lib.sh \ +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh +deleted file mode 100755 +index b609fb6231f48..0000000000000 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh ++++ /dev/null +@@ -1,99 +0,0 @@ +-#!/bin/bash +-# SPDX-License-Identifier: GPL-2.0 +-# +-# Test macvlan over balance-alb +- +-lib_dir=$(dirname "$0") +-source ${lib_dir}/bond_topo_2d1c.sh +- +-m1_ns="m1-$(mktemp -u XXXXXX)" +-m2_ns="m1-$(mktemp -u XXXXXX)" +-m1_ip4="192.0.2.11" +-m1_ip6="2001:db8::11" +-m2_ip4="192.0.2.12" +-m2_ip6="2001:db8::12" +- +-cleanup() +-{ +- ip -n ${m1_ns} link del macv0 +- ip netns del ${m1_ns} +- ip -n ${m2_ns} link del macv0 +- ip netns del ${m2_ns} +- +- client_destroy +- server_destroy +- gateway_destroy +-} +- +-check_connection() +-{ +- local ns=${1} +- local target=${2} +- local message=${3:-"macvlan_over_bond"} +- RET=0 +- +- +- ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null +- check_err $? "ping failed" +- log_test "$mode: $message" +-} +- +-macvlan_over_bond() +-{ +- local param="$1" +- RET=0 +- +- # setup new bond mode +- bond_reset "${param}" +- +- ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge +- ip -n ${s_ns} link set macv0 netns ${m1_ns} +- ip -n ${m1_ns} link set dev macv0 up +- ip -n ${m1_ns} addr add ${m1_ip4}/24 dev macv0 +- ip -n ${m1_ns} addr add ${m1_ip6}/24 dev macv0 +- +- ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge +- ip -n ${s_ns} link set macv0 netns ${m2_ns} +- ip -n ${m2_ns} link set dev macv0 up +- ip -n ${m2_ns} addr add ${m2_ip4}/24 dev macv0 +- ip -n ${m2_ns} addr add ${m2_ip6}/24 dev macv0 +- +- sleep 2 +- +- check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" +- check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" +- check_connection "${c_ns}" "${m1_ip4}" "IPv4: client->macvlan_1" +- check_connection "${c_ns}" "${m1_ip6}" "IPv6: client->macvlan_1" +- check_connection "${c_ns}" "${m2_ip4}" "IPv4: client->macvlan_2" +- check_connection "${c_ns}" "${m2_ip6}" "IPv6: client->macvlan_2" +- check_connection "${m1_ns}" "${m2_ip4}" "IPv4: macvlan_1->macvlan_2" +- check_connection "${m1_ns}" "${m2_ip6}" "IPv6: macvlan_1->macvlan_2" +- +- +- sleep 5 +- +- check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" +- check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" +- check_connection "${m1_ns}" "${c_ip4}" "IPv4: macvlan_1->client" +- check_connection "${m1_ns}" "${c_ip6}" "IPv6: macvlan_1->client" +- check_connection "${m2_ns}" "${c_ip4}" "IPv4: macvlan_2->client" +- check_connection "${m2_ns}" "${c_ip6}" "IPv6: macvlan_2->client" +- check_connection "${m2_ns}" "${m1_ip4}" "IPv4: macvlan_2->macvlan_2" +- check_connection "${m2_ns}" "${m1_ip6}" "IPv6: macvlan_2->macvlan_2" +- +- ip -n ${c_ns} neigh flush dev eth0 +-} +- +-trap cleanup EXIT +- +-setup_prepare +-ip netns add ${m1_ns} +-ip netns add ${m2_ns} +- +-modes="active-backup balance-tlb balance-alb" +- +-for mode in $modes; do +- macvlan_over_bond "mode $mode" +-done +- +-exit $EXIT_STATUS +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +new file mode 100755 +index 0000000000000..c4711272fe45d +--- /dev/null ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -0,0 +1,96 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Test macvlan/ipvlan over bond ++ ++lib_dir=$(dirname "$0") ++source ${lib_dir}/bond_topo_2d1c.sh ++ ++xvlan1_ns="xvlan1-$(mktemp -u XXXXXX)" ++xvlan2_ns="xvlan2-$(mktemp -u XXXXXX)" ++xvlan1_ip4="192.0.2.11" ++xvlan1_ip6="2001:db8::11" ++xvlan2_ip4="192.0.2.12" ++xvlan2_ip6="2001:db8::12" ++ ++cleanup() ++{ ++ client_destroy ++ server_destroy ++ gateway_destroy ++ ++ ip netns del ${xvlan1_ns} ++ ip netns del ${xvlan2_ns} ++} ++ ++check_connection() ++{ ++ local ns=${1} ++ local target=${2} ++ local message=${3} ++ RET=0 ++ ++ ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null ++ check_err $? "ping failed" ++ log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" ++} ++ ++xvlan_over_bond() ++{ ++ local param="$1" ++ local xvlan_type="$2" ++ local xvlan_mode="$3" ++ RET=0 ++ ++ # setup new bond mode ++ bond_reset "${param}" ++ ++ ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} ++ ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan1_ns} ++ ip -n ${xvlan1_ns} link set dev ${xvlan_type}0 up ++ ip -n ${xvlan1_ns} addr add ${xvlan1_ip4}/24 dev ${xvlan_type}0 ++ ip -n ${xvlan1_ns} addr add ${xvlan1_ip6}/24 dev ${xvlan_type}0 ++ ++ ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} ++ ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan2_ns} ++ ip -n ${xvlan2_ns} link set dev ${xvlan_type}0 up ++ ip -n ${xvlan2_ns} addr add ${xvlan2_ip4}/24 dev ${xvlan_type}0 ++ ip -n ${xvlan2_ns} addr add ${xvlan2_ip6}/24 dev ${xvlan_type}0 ++ ++ sleep 2 ++ ++ check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" ++ check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" ++ check_connection "${c_ns}" "${xvlan1_ip4}" "IPv4: client->${xvlan_type}_1" ++ check_connection "${c_ns}" "${xvlan1_ip6}" "IPv6: client->${xvlan_type}_1" ++ check_connection "${c_ns}" "${xvlan2_ip4}" "IPv4: client->${xvlan_type}_2" ++ check_connection "${c_ns}" "${xvlan2_ip6}" "IPv6: client->${xvlan_type}_2" ++ check_connection "${xvlan1_ns}" "${xvlan2_ip4}" "IPv4: ${xvlan_type}_1->${xvlan_type}_2" ++ check_connection "${xvlan1_ns}" "${xvlan2_ip6}" "IPv6: ${xvlan_type}_1->${xvlan_type}_2" ++ ++ check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" ++ check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" ++ check_connection "${xvlan1_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_1->client" ++ check_connection "${xvlan1_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_1->client" ++ check_connection "${xvlan2_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_2->client" ++ check_connection "${xvlan2_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_2->client" ++ check_connection "${xvlan2_ns}" "${xvlan1_ip4}" "IPv4: ${xvlan_type}_2->${xvlan_type}_1" ++ check_connection "${xvlan2_ns}" "${xvlan1_ip6}" "IPv6: ${xvlan_type}_2->${xvlan_type}_1" ++ ++ ip -n ${c_ns} neigh flush dev eth0 ++} ++ ++trap cleanup EXIT ++ ++setup_prepare ++ip netns add ${xvlan1_ns} ++ip netns add ${xvlan2_ns} ++ ++bond_modes="active-backup balance-tlb balance-alb" ++ ++for bond_mode in ${bond_modes}; do ++ xvlan_over_bond "mode ${bond_mode}" macvlan bridge ++ xvlan_over_bond "mode ${bond_mode}" ipvlan l2 ++done ++ ++exit $EXIT_STATUS +diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config +index 899d7fb6ea8e9..dad4e5fda4db3 100644 +--- a/tools/testing/selftests/drivers/net/bonding/config ++++ b/tools/testing/selftests/drivers/net/bonding/config +@@ -3,6 +3,7 @@ CONFIG_BRIDGE=y + CONFIG_DUMMY=y + CONFIG_IPV6=y + CONFIG_MACVLAN=y ++CONFIG_IPVLAN=y + CONFIG_NET_ACT_GACT=y + CONFIG_NET_CLS_FLOWER=y + CONFIG_NET_SCH_INGRESS=y +-- +2.51.0 + diff --git a/queue-6.12/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-6.12/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..e8f34d26c4 --- /dev/null +++ b/queue-6.12/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 41dfb216168c3034b445c0312957290eab1ac9a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 6cc69900b3106..752b75b7170df 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -145,6 +145,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-6.12/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-6.12/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..960b9ca354 --- /dev/null +++ b/queue-6.12/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 58ca6c8c4246262b5c3e3b9fa5044b4d55c77963 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 06c7986131d96..0a7ef770c487c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-6.12/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-6.12/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..43eb7f57ff --- /dev/null +++ b/queue-6.12/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From d921b2aa8be4d0d316053b9991b387e334744cba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index bc24f83339d64..06c7986131d96 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series new file mode 100644 index 0000000000..f073a5834b --- /dev/null +++ b/queue-6.12/series @@ -0,0 +1,291 @@ +smack-deduplicate-does-access-rule-request-transmuta.patch +smack-fix-bug-smack64transmute-set-on-non-directory.patch +smack-deduplicate-xattr-setting-in-smack_inode_init_.patch +smack-always-instantiate-inode-in-smack_inode_init_s.patch +smack-fix-bug-invalid-label-of-unix-socket-file.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +smack-fix-bug-setting-task-label-silently-ignores-in.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +accel-ivpu-prevent-runtime-suspend-during-context-ab.patch +accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +accel-ivpu-make-function-parameter-names-consistent.patch +accel-ivpu-fix-dct-active-percent-format.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +pinctrl-renesas-rzg2l-fix-pmc-restore.patch +clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch +clk-renesas-use-str_on_off-helper.patch +clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch +clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch +drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch +hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch +objtool-fix-standalone-hacks-jump_label.patch +objtool-fix-weak-symbol-detection.patch +wifi-ath10k-avoid-vdev-delete-timeout-when-firmware-.patch +wifi-ath10k-add-missing-include-of-export.h.patch +wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch +wifi-ath11k-restore-register-window-after-global-res.patch +sched-fair-forfeit-vruntime-on-yield.patch +irqchip-irq-bcm7038-l1-fix-section-mismatch.patch +irqchip-irq-bcm7120-l2-fix-section-mismatch.patch +irqchip-irq-brcmstb-l2-fix-section-mismatch.patch +irqchip-imx-mu-msi-fix-section-mismatch.patch +irqchip-renesas-rzg2l-fix-section-mismatch.patch +irqchip-starfive-jh8100-fix-section-mismatch.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +crypto-authenc-correctly-pass-einprogress-back-up-to.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +dt-bindings-clock-qcom-x1e80100-gcc-add-missing-vide.patch +dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch +clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch +block-mq-deadline-introduce-dd_start_request.patch +block-mq-deadline-switch-back-to-a-single-dispatch-l.patch +arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch +perf-annotate-check-return-value-of-evsel__get_arch-.patch +arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch +pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch +clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch +clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch +clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch +soc-switch-back-to-struct-platform_driver-remove.patch +soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +wifi-ath11k-fix-vht-mcs-assignment.patch +wifi-ath11k-fix-peer-he-mcs-assignment.patch +s390-smp-fix-fallback-cpu-detection.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch +arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch +arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch +arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch +arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch +arm-dts-renesas-gose-remove-superfluous-port-propert.patch +arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch +revert-mtd-rawnand-marvell-fix-layouts.patch +mtd-nand-relax-ecc-parameter-validation-check.patch +mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch +perf-remove-get_perf_callchain-init_nr-argument.patch +bpf-refactor-stack-map-trace-depth-calculation-into-.patch +bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch +perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch +task_work-fix-nmi-race-condition.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch +soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch +interconnect-qcom-msm8996-add-missing-link-to-slave_.patch +arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch +interconnect-debugfs-fix-incorrect-error-handling-fo.patch +drm-imagination-fix-reference-to-devm_platform_get_a.patch +perf-lock-contention-load-kernel-map-before-lookup.patch +perf-record-skip-synthesize-event-when-open-evsel-fa.patch +power-supply-rt5033_charger-fix-device-node-referenc.patch +power-supply-cw2015-check-devm_delayed_work_autocanc.patch +power-supply-max17040-check-iio_read_channel_process.patch +power-supply-rt9467-return-error-on-failure-in-rt946.patch +power-supply-rt9467-prevent-using-uninitialized-loca.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch +drm-panthor-handle-errors-returned-by-drm_sched_enti.patch +drm-panthor-fix-group_free_queue-for-partially-initi.patch +drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch +drm-panthor-fix-race-with-suspend-during-unplug.patch +drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch +spi-tegra210-quad-fix-timeout-handling.patch +libbpf-fix-parsing-of-multi-split-btf.patch +arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch +arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch +arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch +x86-boot-fix-page-table-access-in-5-level-to-4-level.patch +efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch +locktorture-fix-memory-leak-in-param_set_cpumask.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +md-fix-rcu-protection-in-md_wakeup_thread.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +scsi-smartpqi-fix-device-resources-accessed-after-de.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch +ntfs3-init-run-lock-for-extend-inode.patch +drm-panthor-fix-potential-memleak-of-vma-structure.patch +scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch +cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch +powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +coresight-change-device-mode-to-atomic-type.patch +coresight-etm4x-correct-polling-idle-bit.patch +coresight-etm4x-extract-the-trace-unit-controlling.patch +coresight-etm4x-add-context-synchronization-before-e.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +bpf-free-special-fields-when-update-lru_-percpu_hash.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-2219 +crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch +s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch +drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +watchdog-starfive-fix-resource-leak-in-probe-error-p.patch +tracefs-fix-a-leak-in-eventfs_create_events_dir.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +block-blk-throttle-fix-throttle-slice-time-for-ssds.patch +drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +bpf-fix-invalid-prog-stats-access-when-update_effect.patch +powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch +drm-msm-a6xx-fix-the-gemnoc-workaround.patch +drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch +ipv6-clear-ra-flags-when-adding-a-static-route.patch +perf-arm-spe-extend-branch-operations.patch +perf-arm_spe-fix-memset-subclass-in-operation.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch +iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch +wifi-mac80211-fix-cmac-functions-not-handling-errors.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch +phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch +phy-freescale-initialize-priv-lock.patch +phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch +phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch +net-phy-adin1100-fix-software-power-down-ready-condi.patch +cpuset-treat-cpusets-in-attaching-as-populated.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ras-report-all-arm-processor-cper-information-to-use.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-starfive-correctly-handle-return-of-sg_nents_.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch +erofs-limit-the-level-of-fs-stacking-for-file-backed.patch +rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch +rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch +asoc-tas2781-correct-the-wrong-period.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch +btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch +um-don-t-rename-vmap-to-kernel_vmap.patch +iomap-factor-out-a-iomap_dio_done-helper.patch +iomap-always-run-error-completions-in-user-context.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch +drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch +asoc-nau8325-use-simple-i2c-probe-function.patch +asoc-nau8325-add-missing-build-config.patch +gfs2-prevent-recursive-memory-reclaim.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +firmware_loader-make-rust_fw_loader_abstractions-sel.patch +greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch +kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ublk-prevent-invalid-access-with-debug.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-typo-in-virtio_device_ready-comment.patch +virtio-fix-whitespace-in-virtio_config_ops.patch +virtio-fix-grammar-in-virtio_queue_info-docs.patch +virtio-fix-virtqueue_set_affinity-docs.patch +vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch +vhost-fix-kthread-worker-cgroup-failure-handling.patch +vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch +arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch +arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +resource-replace-open-coded-resource_intersection.patch +resource-introduce-is_type_match-helper-and-use-it.patch +reinstate-resource-avoid-unnecessary-lookups-in-find.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch +spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch +vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch +net-phy-aquantia-check-for-nvmem-deferral.patch +selftests-bonding-add-ipvlan-over-bond-testing.patch +selftests-bonding-add-delay-before-each-xvlan_over_b.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch +clk-keystone-fix-compile-testing.patch +net-hsr-remove-one-synchronize_rcu-from-hsr_del_port.patch +net-hsr-remove-synchronize_rcu-from-hsr_add_port.patch +net-hsr-create-and-export-hsr_get_port_ndev.patch +net-hsr-create-an-api-to-get-hsr-port-type.patch +net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-tools-mark-split-kallsyms-dsos-as-loaded.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch +9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch +sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch diff --git a/queue-6.12/smack-always-instantiate-inode-in-smack_inode_init_s.patch b/queue-6.12/smack-always-instantiate-inode-in-smack_inode_init_s.patch new file mode 100644 index 0000000000..426a39bf7c --- /dev/null +++ b/queue-6.12/smack-always-instantiate-inode-in-smack_inode_init_s.patch @@ -0,0 +1,70 @@ +From c8ed10130b52a1f6ad31c7f0ea1bf4caf120d039 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:31 +0300 +Subject: smack: always "instantiate" inode in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 69204f6cdb90f56b7ca27966d1080841108fc5de ] + +If memory allocation for the SMACK64TRANSMUTE +xattr value fails in smack_inode_init_security(), +the SMK_INODE_INSTANT flag is not set in +(struct inode_smack *issp)->smk_flags, +leaving the inode as not "instantiated". + +It does not matter if fs frees the inode +after failed smack_inode_init_security() call, +but there is no guarantee for this. + +To be safe, mark the inode as "instantiated", +even if allocation of xattr values fails. + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 586ba83c6e1be..d0a062a20024d 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1032,6 +1032,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); ++ int rc = 0; ++ int transflag = 0; + bool trans_cred; + bool trans_rule; + +@@ -1060,18 +1062,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_inode = dsp; + + if (S_ISDIR(inode->i_mode)) { +- issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ transflag = SMK_INODE_TRANSMUTE; + + if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_TRANSMUTE, + TRANS_TRUE, + TRANS_TRUE_SIZE + )) +- return -ENOMEM; ++ rc = -ENOMEM; + } + } + +- issp->smk_flags |= SMK_INODE_INSTANT; ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ if (rc) ++ return rc; + + return xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, +-- +2.51.0 + diff --git a/queue-6.12/smack-deduplicate-does-access-rule-request-transmuta.patch b/queue-6.12/smack-deduplicate-does-access-rule-request-transmuta.patch new file mode 100644 index 0000000000..36d3e32059 --- /dev/null +++ b/queue-6.12/smack-deduplicate-does-access-rule-request-transmuta.patch @@ -0,0 +1,145 @@ +From 06ca675a2552bcc4ac39f89d51f97bb0b3510d73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:28 +0300 +Subject: smack: deduplicate "does access rule request transmutation" + +From: Konstantin Andreev + +[ Upstream commit 635a01da8385fc00a144ec24684100bd1aa9db11 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 57 +++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 25 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 9e13fd3920630..18e15585dce41 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -979,6 +979,24 @@ static int smack_inode_alloc_security(struct inode *inode) + return 0; + } + ++/** ++ * smk_rule_transmutes - does access rule for (subject,object) contain 't'? ++ * @subject: a pointer to the subject's Smack label entry ++ * @object: a pointer to the object's Smack label entry ++ */ ++static bool ++smk_rule_transmutes(struct smack_known *subject, ++ const struct smack_known *object) ++{ ++ int may; ++ ++ rcu_read_lock(); ++ may = smk_access_entry(subject->smk_known, object->smk_known, ++ &subject->smk_rules); ++ rcu_read_unlock(); ++ return (may > 0) && (may & MAY_TRANSMUTE); ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -994,23 +1012,19 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct xattr *xattrs, int *xattr_count) + { + struct task_smack *tsp = smack_cred(current_cred()); +- struct inode_smack *issp = smack_inode(inode); +- struct smack_known *skp = smk_of_task(tsp); +- struct smack_known *isp = smk_of_inode(inode); ++ struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); + struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); +- int may; ++ bool trans_cred; ++ bool trans_rule; + + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. + */ +- if (tsp->smk_task != tsp->smk_transmuted) { +- rcu_read_lock(); +- may = smk_access_entry(skp->smk_known, dsp->smk_known, +- &skp->smk_rules); +- rcu_read_unlock(); +- } ++ trans_cred = (tsp->smk_task == tsp->smk_transmuted); ++ if (!trans_cred) ++ trans_rule = smk_rule_transmutes(smk_of_task(tsp), dsp); + + /* + * In addition to having smk_task equal to smk_transmuted, +@@ -1018,9 +1032,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * requests transmutation then by all means transmute. + * Mark the inode as changed. + */ +- if ((tsp->smk_task == tsp->smk_transmuted) || +- (may > 0 && ((may & MAY_TRANSMUTE) != 0) && +- smk_inode_transmutable(dir))) { ++ if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { + struct xattr *xattr_transmute; + + /* +@@ -1029,8 +1041,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * inode label was already set correctly in + * smack_inode_alloc_security(). + */ +- if (tsp->smk_task != tsp->smk_transmuted) +- isp = issp->smk_inode = dsp; ++ if (!trans_cred) ++ issp->smk_inode = dsp; + + issp->smk_flags |= SMK_INODE_TRANSMUTE; + xattr_transmute = lsm_get_xattr_slot(xattrs, +@@ -1050,11 +1062,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_flags |= SMK_INODE_INSTANT; + + if (xattr) { +- xattr->value = kstrdup(isp->smk_known, GFP_NOFS); ++ const char *inode_label = issp->smk_inode->smk_known; ++ ++ xattr->value = kstrdup(inode_label, GFP_NOFS); + if (!xattr->value) + return -ENOMEM; + +- xattr->value_len = strlen(isp->smk_known); ++ xattr->value_len = strlen(inode_label); + xattr->name = XATTR_SMACK_SUFFIX; + } + +@@ -4904,7 +4918,6 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + struct task_smack *otsp = smack_cred(old); + struct task_smack *ntsp = smack_cred(new); + struct inode_smack *isp; +- int may; + + /* + * Use the process credential unless all of +@@ -4918,18 +4931,12 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + isp = smack_inode(d_inode(dentry->d_parent)); + + if (isp->smk_flags & SMK_INODE_TRANSMUTE) { +- rcu_read_lock(); +- may = smk_access_entry(otsp->smk_task->smk_known, +- isp->smk_inode->smk_known, +- &otsp->smk_task->smk_rules); +- rcu_read_unlock(); +- + /* + * If the directory is transmuting and the rule + * providing access is transmuting use the containing + * directory label instead of the process label. + */ +- if (may > 0 && (may & MAY_TRANSMUTE)) { ++ if (smk_rule_transmutes(otsp->smk_task, isp->smk_inode)) { + ntsp->smk_task = isp->smk_inode; + ntsp->smk_transmuted = ntsp->smk_task; + } +-- +2.51.0 + diff --git a/queue-6.12/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch b/queue-6.12/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch new file mode 100644 index 0000000000..4198f9a3d6 --- /dev/null +++ b/queue-6.12/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch @@ -0,0 +1,113 @@ +From 2b043c80426181a38e8714cd46e3ad5b054de2ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:30 +0300 +Subject: smack: deduplicate xattr setting in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 8e5d9f916a9678e2dcbed2289b87efd453e4e052 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 56 ++++++++++++++++++++------------------ + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d2fca7b1c6374..586ba83c6e1be 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -997,6 +997,24 @@ smk_rule_transmutes(struct smack_known *subject, + return (may > 0) && (may & MAY_TRANSMUTE); + } + ++static int ++xattr_dupval(struct xattr *xattrs, int *xattr_count, ++ const char *name, const void *value, unsigned int vallen) ++{ ++ struct xattr * const xattr = lsm_get_xattr_slot(xattrs, xattr_count); ++ ++ if (!xattr) ++ return 0; ++ ++ xattr->value = kmemdup(value, vallen, GFP_NOFS); ++ if (!xattr->value) ++ return -ENOMEM; ++ ++ xattr->value_len = vallen; ++ xattr->name = name; ++ return 0; ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -1014,7 +1032,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); +- struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); + bool trans_cred; + bool trans_rule; + +@@ -1033,8 +1050,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * Mark the inode as changed. + */ + if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { +- struct xattr *xattr_transmute; +- + /* + * The caller of smack_dentry_create_files_as() + * should have overridden the current cred, so the +@@ -1046,35 +1061,22 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + + if (S_ISDIR(inode->i_mode)) { + issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; +- } ++ ++ if (xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_TRANSMUTE, ++ TRANS_TRUE, ++ TRANS_TRUE_SIZE ++ )) ++ return -ENOMEM; + } + } + + issp->smk_flags |= SMK_INODE_INSTANT; + +- if (xattr) { +- const char *inode_label = issp->smk_inode->smk_known; +- +- xattr->value = kstrdup(inode_label, GFP_NOFS); +- if (!xattr->value) +- return -ENOMEM; +- +- xattr->value_len = strlen(inode_label); +- xattr->name = XATTR_SMACK_SUFFIX; +- } +- +- return 0; ++ return xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_SUFFIX, ++ issp->smk_inode->smk_known, ++ strlen(issp->smk_inode->smk_known)); + } + + /** +-- +2.51.0 + diff --git a/queue-6.12/smack-fix-bug-invalid-label-of-unix-socket-file.patch b/queue-6.12/smack-fix-bug-invalid-label-of-unix-socket-file.patch new file mode 100644 index 0000000000..1196d78110 --- /dev/null +++ b/queue-6.12/smack-fix-bug-invalid-label-of-unix-socket-file.patch @@ -0,0 +1,200 @@ +From 0303b0b1ecb49d2c37ebc21cd8e8c6a1f43426ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:32 +0300 +Subject: smack: fix bug: invalid label of unix socket file + +From: Konstantin Andreev + +[ Upstream commit 78fc6a94be252b27bb73e4926eed70b5e302a8e0 ] + +According to [1], the label of a UNIX domain socket (UDS) +file (i.e., the filesystem object representing the socket) +is not supposed to participate in Smack security. + +To achieve this, [1] labels UDS files with "*" +in smack_d_instantiate(). + +Before [2], smack_d_instantiate() was responsible +for initializing Smack security for all inodes, +except ones under /proc + +[2] imposed the sole responsibility for initializing +inode security for newly created filesystem objects +on smack_inode_init_security(). + +However, smack_inode_init_security() lacks some logic +present in smack_d_instantiate(). +In particular, it does not label UDS files with "*". + +This patch adds the missing labeling of UDS files +with "*" to smack_inode_init_security(). + +Labeling UDS files with "*" in smack_d_instantiate() +still works for stale UDS files that already exist on +disk. Stale UDS files are useless, but I keep labeling +them for consistency and maybe to make easier for user +to delete them. + +Compared to [1], this version introduces the following +improvements: + + * UDS file label is held inside inode only + and not saved to xattrs. + + * relabeling UDS files (setxattr, removexattr, etc.) + is blocked. + +[1] 2010-11-24 Casey Schaufler +commit b4e0d5f0791b ("Smack: UDS revision") + +[2] 2023-11-16 roberto.sassu +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 5 +++ + security/smack/smack_lsm.c | 58 +++++++++++++++++++------ + 2 files changed, 49 insertions(+), 14 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 6d44f4fdbf59f..1b554b5bf98e6 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -696,6 +696,11 @@ sockets. + A privileged program may set this to match the label of another + task with which it hopes to communicate. + ++UNIX domain socket (UDS) with a BSD address functions both as a file in a ++filesystem and as a socket. As a file, it carries the SMACK64 attribute. This ++attribute is not involved in Smack security enforcement and is immutably ++assigned the label "*". ++ + Smack Netlabel Exceptions + ~~~~~~~~~~~~~~~~~~~~~~~~~ + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d0a062a20024d..c9fbcfb9e6231 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1037,6 +1037,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + bool trans_cred; + bool trans_rule; + ++ /* ++ * UNIX domain sockets use lower level socket data. Let ++ * UDS inode have fixed * label to keep smack_inode_permission() calm ++ * when called from unix_find_bsd() ++ */ ++ if (S_ISSOCK(inode->i_mode)) { ++ /* forced label, no need to save to xattrs */ ++ issp->smk_inode = &smack_known_star; ++ goto instant_inode; ++ } + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. +@@ -1073,14 +1083,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + } + } + +- issp->smk_flags |= (SMK_INODE_INSTANT | transflag); +- if (rc) +- return rc; +- +- return xattr_dupval(xattrs, xattr_count, ++ if (rc == 0) ++ if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, + issp->smk_inode->smk_known, +- strlen(issp->smk_inode->smk_known)); ++ strlen(issp->smk_inode->smk_known) ++ )) ++ rc = -ENOMEM; ++instant_inode: ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ return rc; + } + + /** +@@ -1354,13 +1366,23 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + int check_import = 0; + int check_star = 0; + int rc = 0; ++ umode_t const i_mode = d_backing_inode(dentry)->i_mode; + + /* + * Check label validity here so import won't fail in post_setxattr + */ +- if (strcmp(name, XATTR_NAME_SMACK) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { ++ if (strcmp(name, XATTR_NAME_SMACK) == 0) { ++ /* ++ * UDS inode has fixed label ++ */ ++ if (S_ISSOCK(i_mode)) { ++ rc = -EINVAL; ++ } else { ++ check_priv = 1; ++ check_import = 1; ++ } ++ } else if (strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || ++ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + check_priv = 1; + check_import = 1; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || +@@ -1370,7 +1392,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + check_star = 1; + } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { + check_priv = 1; +- if (!S_ISDIR(d_backing_inode(dentry)->i_mode) || ++ if (!S_ISDIR(i_mode) || + size != TRANS_TRUE_SIZE || + strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) + rc = -EINVAL; +@@ -1501,12 +1523,15 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap, + * Don't do anything special for these. + * XATTR_NAME_SMACKIPIN + * XATTR_NAME_SMACKIPOUT ++ * XATTR_NAME_SMACK if S_ISSOCK (UDS inode has fixed label) + */ + if (strcmp(name, XATTR_NAME_SMACK) == 0) { +- struct super_block *sbp = dentry->d_sb; +- struct superblock_smack *sbsp = smack_superblock(sbp); ++ if (!S_ISSOCK(d_backing_inode(dentry)->i_mode)) { ++ struct super_block *sbp = dentry->d_sb; ++ struct superblock_smack *sbsp = smack_superblock(sbp); + +- isp->smk_inode = sbsp->smk_default; ++ isp->smk_inode = sbsp->smk_default; ++ } + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) + isp->smk_task = NULL; + else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) +@@ -3615,7 +3640,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + + /* +- * UNIX domain sockets use lower level socket data. ++ * UDS inode has fixed label (*) + */ + if (S_ISSOCK(inode->i_mode)) { + final = &smack_known_star; +@@ -4862,6 +4887,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) + + static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) + { ++ /* ++ * UDS inode has fixed label. Ignore nfs label. ++ */ ++ if (S_ISSOCK(inode->i_mode)) ++ return 0; + return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, + ctxlen, 0); + } +-- +2.51.0 + diff --git a/queue-6.12/smack-fix-bug-setting-task-label-silently-ignores-in.patch b/queue-6.12/smack-fix-bug-setting-task-label-silently-ignores-in.patch new file mode 100644 index 0000000000..ef9849828c --- /dev/null +++ b/queue-6.12/smack-fix-bug-setting-task-label-silently-ignores-in.patch @@ -0,0 +1,463 @@ +From 680ec15c0ed2abe13c64129041bae17f83eb5b31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:17 +0300 +Subject: smack: fix bug: setting task label silently ignores input garbage + +From: Konstantin Andreev + +[ Upstream commit 674e2b24791cbe8fd5dc8a0aed4cb4404fcd2028 ] + +This command: + # echo foo/bar >/proc/$$/attr/smack/current + +gives the task a label 'foo' w/o indication +that label does not match input. +Setting the label with lsm_set_self_attr() syscall +behaves identically. + +This occures because: + +1) smk_parse_smack() is used to convert input to a label +2) smk_parse_smack() takes only that part from the + beginning of the input that looks like a label. +3) `/' is prohibited in labels, so only "foo" is taken. + +(2) is by design, because smk_parse_smack() is used +for parsing strings which are more than just a label. + +Silent failure is not a good thing, and there are two +indicators that this was not done intentionally: + + (size >= SMK_LONGLABEL) ~> invalid + +clause at the beginning of the do_setattr() and the +"Returns the length of the smack label" claim +in the do_setattr() description. + +So I fixed this by adding one tiny check: +the taken label length == input length. + +Since input length is now strictly controlled, +I changed the two ways of setting label + + smack_setselfattr(): lsm_set_self_attr() syscall + smack_setprocattr(): > /proc/.../current + +to accommodate the divergence in +what they understand by "input length": + + smack_setselfattr counts mandatory \0 into input length, + smack_setprocattr does not. + + smack_setprocattr allows various trailers after label + +Related changes: + +* fixed description for smk_parse_smack + +* allow unprivileged tasks validate label syntax. + +* extract smk_parse_label_len() from smk_parse_smack() + so parsing may be done w/o string allocation. + +* extract smk_import_valid_label() from smk_import_entry() + to avoid repeated parsing. + +* smk_parse_smack(): scan null-terminated strings + for no more than SMK_LONGLABEL(256) characters + +* smack_setselfattr(): require struct lsm_ctx . flags == 0 + to reserve them for future. + +Fixes: e114e473771c ("Smack: Simplified Mandatory Access Control Kernel") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 11 ++- + security/smack/smack.h | 3 + + security/smack/smack_access.c | 93 ++++++++++++++----- + security/smack/smack_lsm.c | 115 +++++++++++++++--------- + 4 files changed, 156 insertions(+), 66 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 1b554b5bf98e6..c5ed775f2d107 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -601,10 +601,15 @@ specification. + Task Attribute + ~~~~~~~~~~~~~~ + +-The Smack label of a process can be read from /proc//attr/current. A +-process can read its own Smack label from /proc/self/attr/current. A ++The Smack label of a process can be read from ``/proc//attr/current``. A ++process can read its own Smack label from ``/proc/self/attr/current``. A + privileged process can change its own Smack label by writing to +-/proc/self/attr/current but not the label of another process. ++``/proc/self/attr/current`` but not the label of another process. ++ ++Format of writing is : only the label or the label followed by one of the ++3 trailers: ``\n`` (by common agreement for ``/proc/...`` interfaces), ++``\0`` (because some applications incorrectly include it), ++``\n\0`` (because we think some applications may incorrectly include it). + + File Attribute + ~~~~~~~~~~~~~~ +diff --git a/security/smack/smack.h b/security/smack/smack.h +index 1c3656b5e3b91..deb2ef31b63a4 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -285,9 +285,12 @@ int smk_tskacc(struct task_smack *, struct smack_known *, + u32, struct smk_audit_info *); + int smk_curacc(struct smack_known *, u32, struct smk_audit_info *); + struct smack_known *smack_from_secid(const u32); ++int smk_parse_label_len(const char *string, int len); + char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); + struct smack_known *smk_import_entry(const char *, int); ++struct smack_known *smk_import_valid_label(const char *label, int label_len, ++ gfp_t gfp); + void smk_insert_entry(struct smack_known *skp); + struct smack_known *smk_find_entry(const char *); + bool smack_privileged(int cap); +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 585e5e35710b2..37a185ebf5da8 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -435,19 +435,19 @@ struct smack_known *smk_find_entry(const char *string) + } + + /** +- * smk_parse_smack - parse smack label from a text string +- * @string: a text string that might contain a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_parse_label_len - calculate the length of the starting segment ++ * in the string that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated + * +- * Returns a pointer to the clean label or an error code. ++ * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code. + */ +-char *smk_parse_smack(const char *string, int len) ++int smk_parse_label_len(const char *string, int len) + { +- char *smack; + int i; + +- if (len <= 0) +- len = strlen(string) + 1; ++ if (len <= 0 || len > SMK_LONGLABEL) ++ len = SMK_LONGLABEL; + + /* + * Reserve a leading '-' as an indicator that +@@ -455,7 +455,7 @@ char *smk_parse_smack(const char *string, int len) + * including /smack/cipso and /smack/cipso2 + */ + if (string[0] == '-') +- return ERR_PTR(-EINVAL); ++ return -EINVAL; + + for (i = 0; i < len; i++) + if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || +@@ -463,6 +463,25 @@ char *smk_parse_smack(const char *string, int len) + break; + + if (i == 0 || i >= SMK_LONGLABEL) ++ return -EINVAL; ++ ++ return i; ++} ++ ++/** ++ * smk_parse_smack - copy the starting segment in the string ++ * that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the copy of the label or an error code. ++ */ ++char *smk_parse_smack(const char *string, int len) ++{ ++ char *smack; ++ int i = smk_parse_label_len(string, len); ++ ++ if (i < 0) + return ERR_PTR(-EINVAL); + + smack = kstrndup(string, i, GFP_NOFS); +@@ -546,31 +565,25 @@ int smack_populate_secattr(struct smack_known *skp) + } + + /** +- * smk_import_entry - import a label, return the list entry +- * @string: a text string that might be a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_import_valid_allocated_label - import a label, return the list entry ++ * @smack: a text string that is a valid Smack label and may be kfree()ed. ++ * It is consumed: either becomes a part of the entry or kfree'ed. + * +- * Returns a pointer to the entry in the label list that +- * matches the passed string, adding it if necessary, +- * or an error code. ++ * Returns: see description of smk_import_entry() + */ +-struct smack_known *smk_import_entry(const char *string, int len) ++static struct smack_known * ++smk_import_allocated_label(char *smack, gfp_t gfp) + { + struct smack_known *skp; +- char *smack; + int rc; + +- smack = smk_parse_smack(string, len); +- if (IS_ERR(smack)) +- return ERR_CAST(smack); +- + mutex_lock(&smack_known_lock); + + skp = smk_find_entry(smack); + if (skp != NULL) + goto freeout; + +- skp = kzalloc(sizeof(*skp), GFP_NOFS); ++ skp = kzalloc(sizeof(*skp), gfp); + if (skp == NULL) { + skp = ERR_PTR(-ENOMEM); + goto freeout; +@@ -600,6 +613,42 @@ struct smack_known *smk_import_entry(const char *string, int len) + return skp; + } + ++/** ++ * smk_import_entry - import a label, return the list entry ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the entry in the label list that ++ * matches the passed string, adding it if necessary, ++ * or an error code. ++ */ ++struct smack_known *smk_import_entry(const char *string, int len) ++{ ++ char *smack = smk_parse_smack(string, len); ++ ++ if (IS_ERR(smack)) ++ return ERR_CAST(smack); ++ ++ return smk_import_allocated_label(smack, GFP_NOFS); ++} ++ ++/** ++ * smk_import_valid_label - import a label, return the list entry ++ * @label a text string that is a valid Smack label, not null-terminated ++ * ++ * Returns: see description of smk_import_entry() ++ */ ++struct smack_known * ++smk_import_valid_label(const char *label, int label_len, gfp_t gfp) ++{ ++ char *smack = kstrndup(label, label_len, gfp); ++ ++ if (!smack) ++ return ERR_PTR(-ENOMEM); ++ ++ return smk_import_allocated_label(smack, gfp); ++} ++ + /** + * smack_from_secid - find the Smack label associated with a secid + * @secid: an integer that might be associated with a Smack label +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index ce63e1439edbd..c243adb137402 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3718,7 +3718,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * @attr: which attribute to fetch + * @ctx: buffer to receive the result + * @size: available size in, actual size out +- * @flags: unused ++ * @flags: reserved, currently zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3779,57 +3779,52 @@ static int smack_getprocattr(struct task_struct *p, const char *name, char **val + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns zero on success or an error code + */ +-static int do_setattr(u64 attr, void *value, size_t size) ++static int do_setattr(unsigned int attr, void *value, size_t size) + { + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- char *labelstr; +- int rc = 0; +- +- if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) +- return -EPERM; ++ int label_len; + ++ /* ++ * let unprivileged user validate input, check permissions later ++ */ + if (value == NULL || size == 0 || size >= SMK_LONGLABEL) + return -EINVAL; + +- if (attr != LSM_ATTR_CURRENT) +- return -EOPNOTSUPP; +- +- labelstr = smk_parse_smack(value, size); +- if (IS_ERR(labelstr)) +- return PTR_ERR(labelstr); ++ label_len = smk_parse_label_len(value, size); ++ if (label_len < 0 || label_len != size) ++ return -EINVAL; + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (labelstr[1] == '\0' /* '@', '*' */) { +- const char c = labelstr[0]; ++ if (label_len == 1 /* '@', '*' */) { ++ const char c = *(const char *)value; + + if (c == *smack_known_web.smk_known || +- c == *smack_known_star.smk_known) { +- rc = -EPERM; +- goto free_labelstr; +- } ++ c == *smack_known_star.smk_known) ++ return -EPERM; + } + + if (!smack_privileged(CAP_MAC_ADMIN)) { + const struct smack_known_list_elem *sklep; +- list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) +- goto free_labelstr; +- rc = -EPERM; +- } ++ list_for_each_entry(sklep, &tsp->smk_relabel, list) { ++ const char *cp = sklep->smk_label->smk_known; + +-free_labelstr: +- kfree(labelstr); +- if (rc) ++ if (strlen(cp) == label_len && ++ strncmp(cp, value, label_len) == 0) ++ goto in_relabel; ++ } + return -EPERM; ++in_relabel: ++ ; ++ } + +- skp = smk_import_entry(value, size); ++ skp = smk_import_valid_label(value, label_len, GFP_KERNEL); + if (IS_ERR(skp)) + return PTR_ERR(skp); + +@@ -3845,7 +3840,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + smk_destroy_label_list(&tsp->smk_relabel); + + commit_creds(new); +- return size; ++ return 0; + } + + /** +@@ -3853,7 +3848,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + * @attr: which attribute to set + * @ctx: buffer containing the data + * @size: size of @ctx +- * @flags: unused ++ * @flags: reserved, must be zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3863,12 +3858,26 @@ static int do_setattr(u64 attr, void *value, size_t size) + static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + u32 size, u32 flags) + { +- int rc; ++ if (attr != LSM_ATTR_CURRENT) ++ return -EOPNOTSUPP; + +- rc = do_setattr(attr, ctx->ctx, ctx->ctx_len); +- if (rc > 0) +- return 0; +- return rc; ++ if (ctx->flags) ++ return -EINVAL; ++ /* ++ * string must have \0 terminator, included in ctx->ctx ++ * (see description of struct lsm_ctx) ++ */ ++ if (ctx->ctx_len == 0) ++ return -EINVAL; ++ ++ if (ctx->ctx[ctx->ctx_len - 1] != '\0') ++ return -EINVAL; ++ /* ++ * other do_setattr() caller, smack_setprocattr(), ++ * does not count \0 into size, so ++ * decreasing length by 1 to accommodate the divergence. ++ */ ++ return do_setattr(attr, ctx->ctx, ctx->ctx_len - 1); + } + + /** +@@ -3880,15 +3889,39 @@ static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns the size of the input value or an error code + */ + static int smack_setprocattr(const char *name, void *value, size_t size) + { +- int attr = lsm_name_to_attr(name); ++ size_t realsize = size; ++ unsigned int attr = lsm_name_to_attr(name); + +- if (attr != LSM_ATTR_UNDEF) +- return do_setattr(attr, value, size); +- return -EINVAL; ++ switch (attr) { ++ case LSM_ATTR_UNDEF: return -EINVAL; ++ default: return -EOPNOTSUPP; ++ case LSM_ATTR_CURRENT: ++ ; ++ } ++ ++ /* ++ * The value for the "current" attribute is the label ++ * followed by one of the 4 trailers: none, \0, \n, \n\0 ++ * ++ * I.e. following inputs are accepted as 3-characters long label "foo": ++ * ++ * "foo" (3 characters) ++ * "foo\0" (4 characters) ++ * "foo\n" (4 characters) ++ * "foo\n\0" (5 characters) ++ */ ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\0')) ++ --realsize; ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\n')) ++ --realsize; ++ ++ return do_setattr(attr, value, realsize) ? : size; + } + + /** +-- +2.51.0 + diff --git a/queue-6.12/smack-fix-bug-smack64transmute-set-on-non-directory.patch b/queue-6.12/smack-fix-bug-smack64transmute-set-on-non-directory.patch new file mode 100644 index 0000000000..8270e085ba --- /dev/null +++ b/queue-6.12/smack-fix-bug-smack64transmute-set-on-non-directory.patch @@ -0,0 +1,82 @@ +From 2f3b4616b0c4dcad268abbaf26819d2168524e38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:29 +0300 +Subject: smack: fix bug: SMACK64TRANSMUTE set on non-directory + +From: Konstantin Andreev + +[ Upstream commit 195da3ff244deff119c3f5244b464b2236ea1725 ] + +When a new file system object is created +and the conditions for label transmutation are met, +the SMACK64TRANSMUTE extended attribute is set +on the object regardless of its type: +file, pipe, socket, symlink, or directory. + +However, +SMACK64TRANSMUTE may only be set on directories. + +This bug is a combined effect of the commits [1] and [2] +which both transfer functionality +from smack_d_instantiate() to smack_inode_init_security(), +but only in part. + +Commit [1] set blank SMACK64TRANSMUTE on improper object types. +Commit [2] set "TRUE" SMACK64TRANSMUTE on improper object types. + +[1] 2023-06-10, +Fixes: baed456a6a2f ("smack: Set the SMACK64TRANSMUTE xattr in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20230610075738.3273764-3-roberto.sassu@huaweicloud.com/ + +[2] 2023-11-16, +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 18e15585dce41..d2fca7b1c6374 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1044,18 +1044,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + if (!trans_cred) + issp->smk_inode = dsp; + +- issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ if (S_ISDIR(inode->i_mode)) { ++ issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ xattr_transmute = lsm_get_xattr_slot(xattrs, ++ xattr_count); ++ if (xattr_transmute) { ++ xattr_transmute->value = kmemdup(TRANS_TRUE, ++ TRANS_TRUE_SIZE, ++ GFP_NOFS); ++ if (!xattr_transmute->value) ++ return -ENOMEM; ++ ++ xattr_transmute->value_len = TRANS_TRUE_SIZE; ++ xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ } + } + } + +-- +2.51.0 + diff --git a/queue-6.12/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-6.12/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..81cf4a02bc --- /dev/null +++ b/queue-6.12/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From 0a360baf3f6bf21d19c2d03ec01849c4f30bd0ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index c9fbcfb9e6231..ce63e1439edbd 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3786,8 +3786,8 @@ static int do_setattr(u64 attr, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3798,28 +3798,41 @@ static int do_setattr(u64 attr, void *value, size_t size) + if (attr != LSM_ATTR_CURRENT) + return -EOPNOTSUPP; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.12/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch b/queue-6.12/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch new file mode 100644 index 0000000000..8c83cc1e72 --- /dev/null +++ b/queue-6.12/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch @@ -0,0 +1,60 @@ +From d4c30c65a0725693483c6f2fd0d2099afa9f3ce3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 00:02:15 +0800 +Subject: soc: qcom: gsbi: fix double disable caused by devm + +From: Haotian Zhang + +[ Upstream commit 2286e18e3937c69cc103308a8c1d4898d8a7b04f ] + +In the commit referenced by the Fixes tag, devm_clk_get_enabled() was +introduced to replace devm_clk_get() and clk_prepare_enable(). While +the clk_disable_unprepare() call in the error path was correctly +removed, the one in the remove function was overlooked, leading to a +double disable issue. + +Remove the redundant clk_disable_unprepare() call from gsbi_remove() +to fix this issue. Since all resources are now managed by devres +and will be automatically released, the remove function serves no purpose +and can be deleted entirely. + +Fixes: 489d7a8cc286 ("soc: qcom: use devm_clk_get_enabled() in gsbi_probe()") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/stable/20251020160215.523-1-vulab%40iscas.ac.cn +Link: https://lore.kernel.org/r/20251020160215.523-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/qcom_gsbi.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c +index 8f1158e0c6313..a25d1de592f06 100644 +--- a/drivers/soc/qcom/qcom_gsbi.c ++++ b/drivers/soc/qcom/qcom_gsbi.c +@@ -212,13 +212,6 @@ static int gsbi_probe(struct platform_device *pdev) + return of_platform_populate(node, NULL, NULL, &pdev->dev); + } + +-static void gsbi_remove(struct platform_device *pdev) +-{ +- struct gsbi_info *gsbi = platform_get_drvdata(pdev); +- +- clk_disable_unprepare(gsbi->hclk); +-} +- + static const struct of_device_id gsbi_dt_match[] = { + { .compatible = "qcom,gsbi-v1.0.0", }, + { }, +@@ -232,7 +225,6 @@ static struct platform_driver gsbi_driver = { + .of_match_table = gsbi_dt_match, + }, + .probe = gsbi_probe, +- .remove = gsbi_remove, + }; + + module_platform_driver(gsbi_driver); +-- +2.51.0 + diff --git a/queue-6.12/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.12/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..0d6f0a2546 --- /dev/null +++ b/queue-6.12/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,51 @@ +From 1ee461156d6a26b31a97b8b5e931cbb360fdb0af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:27:33 +0800 +Subject: soc: qcom: smem: fix hwspinlock resource leak in probe error paths + +From: Haotian Zhang + +[ Upstream commit dc5db35073a19f6d3c30bea367b551c1a784ef8f ] + +The hwspinlock acquired via hwspin_lock_request_specific() is not +released on several error paths. This results in resource leakage +when probe fails. + +Switch to devm_hwspin_lock_request_specific() to automatically +handle cleanup on probe failure. Remove the manual hwspin_lock_free() +in qcom_smem_remove() as devm handles it automatically. + +Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/smem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index 56eea77395bf2..170f88ce0e50e 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1186,7 +1186,7 @@ static int qcom_smem_probe(struct platform_device *pdev) + return hwlock_id; + } + +- smem->hwlock = hwspin_lock_request_specific(hwlock_id); ++ smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); + if (!smem->hwlock) + return -ENXIO; + +@@ -1239,7 +1239,6 @@ static void qcom_smem_remove(struct platform_device *pdev) + { + platform_device_unregister(__smem->socinfo); + +- hwspin_lock_free(__smem->hwlock); + __smem = NULL; + } + +-- +2.51.0 + diff --git a/queue-6.12/soc-switch-back-to-struct-platform_driver-remove.patch b/queue-6.12/soc-switch-back-to-struct-platform_driver-remove.patch new file mode 100644 index 0000000000..e3f92271c8 --- /dev/null +++ b/queue-6.12/soc-switch-back-to-struct-platform_driver-remove.patch @@ -0,0 +1,687 @@ +From bc99672435cbc7658ed77ddef9e445bc7812444c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Oct 2024 08:48:58 +0100 +Subject: soc: Switch back to struct platform_driver::remove() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 511c06e3903563dba4472430e1b586745b6ae238 ] + +After commit 0edb555a65d1 ("platform: Make platform_driver::remove() +return void") .remove() is (again) the right callback to implement for +platform drivers. + +Convert all platform drivers below drivers/soc to use .remove(), with +the eventual goal to drop struct platform_driver::remove_new(). As +.remove() and .remove_new() have the same prototypes, conversion is done +by just changing the structure member name in the driver initializer. + +On the way do a few whitespace changes to make indention consistent. + +Signed-off-by: Uwe Kleine-König +Acked-by: Heiko Stuebner +Acked-by: Herve Codina # for fsl/qe/{qmc,tsa}.c +Acked-by: Bjorn Andersson # qcom parts +Acked-by: Gabriel Somlo +Acked-by: Andrew Jeffery # aspeed +Link: https://lore.kernel.org/r/20241029074859.509587-2-u.kleine-koenig@baylibre.com +Signed-off-by: Arnd Bergmann +Stable-dep-of: 2286e18e3937 ("soc: qcom: gsbi: fix double disable caused by devm") +Signed-off-by: Sasha Levin +--- + drivers/soc/aspeed/aspeed-lpc-ctrl.c | 2 +- + drivers/soc/aspeed/aspeed-lpc-snoop.c | 2 +- + drivers/soc/aspeed/aspeed-p2a-ctrl.c | 2 +- + drivers/soc/aspeed/aspeed-uart-routing.c | 2 +- + drivers/soc/fsl/dpaa2-console.c | 2 +- + drivers/soc/fsl/qe/qmc.c | 2 +- + drivers/soc/fsl/qe/tsa.c | 2 +- + drivers/soc/fujitsu/a64fx-diag.c | 2 +- + drivers/soc/hisilicon/kunpeng_hccs.c | 2 +- + drivers/soc/ixp4xx/ixp4xx-npe.c | 2 +- + drivers/soc/ixp4xx/ixp4xx-qmgr.c | 2 +- + drivers/soc/litex/litex_soc_ctrl.c | 2 +- + drivers/soc/loongson/loongson2_guts.c | 2 +- + drivers/soc/mediatek/mtk-devapc.c | 2 +- + drivers/soc/mediatek/mtk-mmsys.c | 2 +- + drivers/soc/mediatek/mtk-socinfo.c | 2 +- + drivers/soc/microchip/mpfs-sys-controller.c | 2 +- + drivers/soc/pxa/ssp.c | 2 +- + drivers/soc/qcom/icc-bwmon.c | 2 +- + drivers/soc/qcom/llcc-qcom.c | 2 +- + drivers/soc/qcom/ocmem.c | 2 +- + drivers/soc/qcom/pmic_glink.c | 2 +- + drivers/soc/qcom/qcom_aoss.c | 2 +- + drivers/soc/qcom/qcom_gsbi.c | 2 +- + drivers/soc/qcom/qcom_stats.c | 2 +- + drivers/soc/qcom/ramp_controller.c | 4 ++-- + drivers/soc/qcom/rmtfs_mem.c | 2 +- + drivers/soc/qcom/rpm-proc.c | 2 +- + drivers/soc/qcom/rpm_master_stats.c | 2 +- + drivers/soc/qcom/smem.c | 2 +- + drivers/soc/qcom/smp2p.c | 2 +- + drivers/soc/qcom/smsm.c | 6 +++--- + drivers/soc/qcom/socinfo.c | 2 +- + drivers/soc/rockchip/io-domain.c | 8 ++++---- + drivers/soc/samsung/exynos-chipid.c | 4 ++-- + drivers/soc/tegra/cbb/tegra194-cbb.c | 2 +- + drivers/soc/ti/k3-ringacc.c | 2 +- + drivers/soc/ti/knav_dma.c | 4 ++-- + drivers/soc/ti/knav_qmss_queue.c | 2 +- + drivers/soc/ti/pm33xx.c | 2 +- + drivers/soc/ti/pruss.c | 4 ++-- + drivers/soc/ti/smartreflex.c | 2 +- + drivers/soc/ti/wkup_m3_ipc.c | 2 +- + drivers/soc/xilinx/xlnx_event_manager.c | 2 +- + drivers/soc/xilinx/zynqmp_power.c | 2 +- + 45 files changed, 54 insertions(+), 54 deletions(-) + +diff --git a/drivers/soc/aspeed/aspeed-lpc-ctrl.c b/drivers/soc/aspeed/aspeed-lpc-ctrl.c +index e87038009d1b2..ee58151bd69ec 100644 +--- a/drivers/soc/aspeed/aspeed-lpc-ctrl.c ++++ b/drivers/soc/aspeed/aspeed-lpc-ctrl.c +@@ -353,7 +353,7 @@ static struct platform_driver aspeed_lpc_ctrl_driver = { + .of_match_table = aspeed_lpc_ctrl_match, + }, + .probe = aspeed_lpc_ctrl_probe, +- .remove_new = aspeed_lpc_ctrl_remove, ++ .remove = aspeed_lpc_ctrl_remove, + }; + + module_platform_driver(aspeed_lpc_ctrl_driver); +diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c +index 54db2abc2e2a7..fc3a2c41cc107 100644 +--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c ++++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c +@@ -388,7 +388,7 @@ static struct platform_driver aspeed_lpc_snoop_driver = { + .of_match_table = aspeed_lpc_snoop_match, + }, + .probe = aspeed_lpc_snoop_probe, +- .remove_new = aspeed_lpc_snoop_remove, ++ .remove = aspeed_lpc_snoop_remove, + }; + + module_platform_driver(aspeed_lpc_snoop_driver); +diff --git a/drivers/soc/aspeed/aspeed-p2a-ctrl.c b/drivers/soc/aspeed/aspeed-p2a-ctrl.c +index 8610ddacc7bc9..6cc943744e129 100644 +--- a/drivers/soc/aspeed/aspeed-p2a-ctrl.c ++++ b/drivers/soc/aspeed/aspeed-p2a-ctrl.c +@@ -431,7 +431,7 @@ static struct platform_driver aspeed_p2a_ctrl_driver = { + .of_match_table = aspeed_p2a_ctrl_match, + }, + .probe = aspeed_p2a_ctrl_probe, +- .remove_new = aspeed_p2a_ctrl_remove, ++ .remove = aspeed_p2a_ctrl_remove, + }; + + module_platform_driver(aspeed_p2a_ctrl_driver); +diff --git a/drivers/soc/aspeed/aspeed-uart-routing.c b/drivers/soc/aspeed/aspeed-uart-routing.c +index a2195f062e01b..0191e36e66e10 100644 +--- a/drivers/soc/aspeed/aspeed-uart-routing.c ++++ b/drivers/soc/aspeed/aspeed-uart-routing.c +@@ -589,7 +589,7 @@ static struct platform_driver aspeed_uart_routing_driver = { + .of_match_table = aspeed_uart_routing_table, + }, + .probe = aspeed_uart_routing_probe, +- .remove_new = aspeed_uart_routing_remove, ++ .remove = aspeed_uart_routing_remove, + }; + + module_platform_driver(aspeed_uart_routing_driver); +diff --git a/drivers/soc/fsl/dpaa2-console.c b/drivers/soc/fsl/dpaa2-console.c +index 6dbc77db77184..6310f54e68a21 100644 +--- a/drivers/soc/fsl/dpaa2-console.c ++++ b/drivers/soc/fsl/dpaa2-console.c +@@ -320,7 +320,7 @@ static struct platform_driver dpaa2_console_driver = { + .of_match_table = dpaa2_console_match_table, + }, + .probe = dpaa2_console_probe, +- .remove_new = dpaa2_console_remove, ++ .remove = dpaa2_console_remove, + }; + module_platform_driver(dpaa2_console_driver); + +diff --git a/drivers/soc/fsl/qe/qmc.c b/drivers/soc/fsl/qe/qmc.c +index b3f773e135fd4..36c0ccc06151f 100644 +--- a/drivers/soc/fsl/qe/qmc.c ++++ b/drivers/soc/fsl/qe/qmc.c +@@ -2094,7 +2094,7 @@ static struct platform_driver qmc_driver = { + .of_match_table = of_match_ptr(qmc_id_table), + }, + .probe = qmc_probe, +- .remove_new = qmc_remove, ++ .remove = qmc_remove, + }; + module_platform_driver(qmc_driver); + +diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c +index f0889b3fcaf2c..515da9b45c2c3 100644 +--- a/drivers/soc/fsl/qe/tsa.c ++++ b/drivers/soc/fsl/qe/tsa.c +@@ -1086,7 +1086,7 @@ static struct platform_driver tsa_driver = { + .of_match_table = of_match_ptr(tsa_id_table), + }, + .probe = tsa_probe, +- .remove_new = tsa_remove, ++ .remove = tsa_remove, + }; + module_platform_driver(tsa_driver); + +diff --git a/drivers/soc/fujitsu/a64fx-diag.c b/drivers/soc/fujitsu/a64fx-diag.c +index 330901893577e..76cb0b6a221c2 100644 +--- a/drivers/soc/fujitsu/a64fx-diag.c ++++ b/drivers/soc/fujitsu/a64fx-diag.c +@@ -142,7 +142,7 @@ static struct platform_driver a64fx_diag_driver = { + .acpi_match_table = ACPI_PTR(a64fx_diag_acpi_match), + }, + .probe = a64fx_diag_probe, +- .remove_new = a64fx_diag_remove, ++ .remove = a64fx_diag_remove, + }; + + module_platform_driver(a64fx_diag_driver); +diff --git a/drivers/soc/hisilicon/kunpeng_hccs.c b/drivers/soc/hisilicon/kunpeng_hccs.c +index e882a61636ec8..8f51e59c9bb19 100644 +--- a/drivers/soc/hisilicon/kunpeng_hccs.c ++++ b/drivers/soc/hisilicon/kunpeng_hccs.c +@@ -1348,7 +1348,7 @@ MODULE_DEVICE_TABLE(acpi, hccs_acpi_match); + + static struct platform_driver hccs_driver = { + .probe = hccs_probe, +- .remove_new = hccs_remove, ++ .remove = hccs_remove, + .driver = { + .name = "kunpeng_hccs", + .acpi_match_table = hccs_acpi_match, +diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c +index 34a6f187c220d..33e2e0366f19c 100644 +--- a/drivers/soc/ixp4xx/ixp4xx-npe.c ++++ b/drivers/soc/ixp4xx/ixp4xx-npe.c +@@ -759,7 +759,7 @@ static struct platform_driver ixp4xx_npe_driver = { + .of_match_table = ixp4xx_npe_of_match, + }, + .probe = ixp4xx_npe_probe, +- .remove_new = ixp4xx_npe_remove, ++ .remove = ixp4xx_npe_remove, + }; + module_platform_driver(ixp4xx_npe_driver); + +diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c +index cb112f3643e97..475e229039e30 100644 +--- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c ++++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c +@@ -461,7 +461,7 @@ static struct platform_driver ixp4xx_qmgr_driver = { + .of_match_table = ixp4xx_qmgr_of_match, + }, + .probe = ixp4xx_qmgr_probe, +- .remove_new = ixp4xx_qmgr_remove, ++ .remove = ixp4xx_qmgr_remove, + }; + module_platform_driver(ixp4xx_qmgr_driver); + +diff --git a/drivers/soc/litex/litex_soc_ctrl.c b/drivers/soc/litex/litex_soc_ctrl.c +index 72c44119dd541..d08bfc8ef7be7 100644 +--- a/drivers/soc/litex/litex_soc_ctrl.c ++++ b/drivers/soc/litex/litex_soc_ctrl.c +@@ -131,7 +131,7 @@ static struct platform_driver litex_soc_ctrl_driver = { + .of_match_table = litex_soc_ctrl_of_match, + }, + .probe = litex_soc_ctrl_probe, +- .remove_new = litex_soc_ctrl_remove, ++ .remove = litex_soc_ctrl_remove, + }; + + module_platform_driver(litex_soc_ctrl_driver); +diff --git a/drivers/soc/loongson/loongson2_guts.c b/drivers/soc/loongson/loongson2_guts.c +index 1fcf7ca8083e1..16913c3ef65ca 100644 +--- a/drivers/soc/loongson/loongson2_guts.c ++++ b/drivers/soc/loongson/loongson2_guts.c +@@ -172,7 +172,7 @@ static struct platform_driver loongson2_guts_driver = { + .of_match_table = loongson2_guts_of_match, + }, + .probe = loongson2_guts_probe, +- .remove_new = loongson2_guts_remove, ++ .remove = loongson2_guts_remove, + }; + + static int __init loongson2_guts_init(void) +diff --git a/drivers/soc/mediatek/mtk-devapc.c b/drivers/soc/mediatek/mtk-devapc.c +index d83a46334adbb..f54c966138b5b 100644 +--- a/drivers/soc/mediatek/mtk-devapc.c ++++ b/drivers/soc/mediatek/mtk-devapc.c +@@ -310,7 +310,7 @@ static void mtk_devapc_remove(struct platform_device *pdev) + + static struct platform_driver mtk_devapc_driver = { + .probe = mtk_devapc_probe, +- .remove_new = mtk_devapc_remove, ++ .remove = mtk_devapc_remove, + .driver = { + .name = "mtk-devapc", + .of_match_table = mtk_devapc_dt_match, +diff --git a/drivers/soc/mediatek/mtk-mmsys.c b/drivers/soc/mediatek/mtk-mmsys.c +index 938240714e54c..bb4639ca0b8cd 100644 +--- a/drivers/soc/mediatek/mtk-mmsys.c ++++ b/drivers/soc/mediatek/mtk-mmsys.c +@@ -487,7 +487,7 @@ static struct platform_driver mtk_mmsys_drv = { + .of_match_table = of_match_mtk_mmsys, + }, + .probe = mtk_mmsys_probe, +- .remove_new = mtk_mmsys_remove, ++ .remove = mtk_mmsys_remove, + }; + module_platform_driver(mtk_mmsys_drv); + +diff --git a/drivers/soc/mediatek/mtk-socinfo.c b/drivers/soc/mediatek/mtk-socinfo.c +index 74672a9d6d13d..123b12cd25432 100644 +--- a/drivers/soc/mediatek/mtk-socinfo.c ++++ b/drivers/soc/mediatek/mtk-socinfo.c +@@ -187,7 +187,7 @@ static void mtk_socinfo_remove(struct platform_device *pdev) + + static struct platform_driver mtk_socinfo = { + .probe = mtk_socinfo_probe, +- .remove_new = mtk_socinfo_remove, ++ .remove = mtk_socinfo_remove, + .driver = { + .name = "mtk-socinfo", + }, +diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c +index 7a4936019329c..30bc45d17d343 100644 +--- a/drivers/soc/microchip/mpfs-sys-controller.c ++++ b/drivers/soc/microchip/mpfs-sys-controller.c +@@ -232,7 +232,7 @@ static struct platform_driver mpfs_sys_controller_driver = { + .of_match_table = mpfs_sys_controller_of_match, + }, + .probe = mpfs_sys_controller_probe, +- .remove_new = mpfs_sys_controller_remove, ++ .remove = mpfs_sys_controller_remove, + }; + module_platform_driver(mpfs_sys_controller_driver); + +diff --git a/drivers/soc/pxa/ssp.c b/drivers/soc/pxa/ssp.c +index 854d32e045583..bb0062c165fe9 100644 +--- a/drivers/soc/pxa/ssp.c ++++ b/drivers/soc/pxa/ssp.c +@@ -197,7 +197,7 @@ static const struct platform_device_id ssp_id_table[] = { + + static struct platform_driver pxa_ssp_driver = { + .probe = pxa_ssp_probe, +- .remove_new = pxa_ssp_remove, ++ .remove = pxa_ssp_remove, + .driver = { + .name = "pxa2xx-ssp", + .of_match_table = of_match_ptr(pxa_ssp_of_ids), +diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c +index f9235bc3aa3bb..3dfa448bf8cf9 100644 +--- a/drivers/soc/qcom/icc-bwmon.c ++++ b/drivers/soc/qcom/icc-bwmon.c +@@ -872,7 +872,7 @@ MODULE_DEVICE_TABLE(of, bwmon_of_match); + + static struct platform_driver bwmon_driver = { + .probe = bwmon_probe, +- .remove_new = bwmon_remove, ++ .remove = bwmon_remove, + .driver = { + .name = "qcom-bwmon", + .of_match_table = bwmon_of_match, +diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c +index 133dc48333135..0278e1854af06 100644 +--- a/drivers/soc/qcom/llcc-qcom.c ++++ b/drivers/soc/qcom/llcc-qcom.c +@@ -3511,7 +3511,7 @@ static struct platform_driver qcom_llcc_driver = { + .of_match_table = qcom_llcc_of_match, + }, + .probe = qcom_llcc_probe, +- .remove_new = qcom_llcc_remove, ++ .remove = qcom_llcc_remove, + }; + module_platform_driver(qcom_llcc_driver); + +diff --git a/drivers/soc/qcom/ocmem.c b/drivers/soc/qcom/ocmem.c +index ff8df7d75d6b2..9c3bd37b6579d 100644 +--- a/drivers/soc/qcom/ocmem.c ++++ b/drivers/soc/qcom/ocmem.c +@@ -439,7 +439,7 @@ MODULE_DEVICE_TABLE(of, ocmem_of_match); + + static struct platform_driver ocmem_driver = { + .probe = ocmem_dev_probe, +- .remove_new = ocmem_dev_remove, ++ .remove = ocmem_dev_remove, + .driver = { + .name = "ocmem", + .of_match_table = ocmem_of_match, +diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c +index 5963f49f6e6e6..22b81b9758b59 100644 +--- a/drivers/soc/qcom/pmic_glink.c ++++ b/drivers/soc/qcom/pmic_glink.c +@@ -404,7 +404,7 @@ MODULE_DEVICE_TABLE(of, pmic_glink_of_match); + + static struct platform_driver pmic_glink_driver = { + .probe = pmic_glink_probe, +- .remove_new = pmic_glink_remove, ++ .remove = pmic_glink_remove, + .driver = { + .name = "qcom_pmic_glink", + .of_match_table = pmic_glink_of_match, +diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c +index 60af26667bce4..0320ad3b91483 100644 +--- a/drivers/soc/qcom/qcom_aoss.c ++++ b/drivers/soc/qcom/qcom_aoss.c +@@ -664,7 +664,7 @@ static struct platform_driver qmp_driver = { + .suppress_bind_attrs = true, + }, + .probe = qmp_probe, +- .remove_new = qmp_remove, ++ .remove = qmp_remove, + }; + module_platform_driver(qmp_driver); + +diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c +index f04b9a324ea9c..8f1158e0c6313 100644 +--- a/drivers/soc/qcom/qcom_gsbi.c ++++ b/drivers/soc/qcom/qcom_gsbi.c +@@ -232,7 +232,7 @@ static struct platform_driver gsbi_driver = { + .of_match_table = gsbi_dt_match, + }, + .probe = gsbi_probe, +- .remove_new = gsbi_remove, ++ .remove = gsbi_remove, + }; + + module_platform_driver(gsbi_driver); +diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c +index c429d5154aaec..5de99cf59b9fb 100644 +--- a/drivers/soc/qcom/qcom_stats.c ++++ b/drivers/soc/qcom/qcom_stats.c +@@ -274,7 +274,7 @@ MODULE_DEVICE_TABLE(of, qcom_stats_table); + + static struct platform_driver qcom_stats = { + .probe = qcom_stats_probe, +- .remove_new = qcom_stats_remove, ++ .remove = qcom_stats_remove, + .driver = { + .name = "qcom_stats", + .of_match_table = qcom_stats_table, +diff --git a/drivers/soc/qcom/ramp_controller.c b/drivers/soc/qcom/ramp_controller.c +index e9a0cca071892..349bdfbc61eff 100644 +--- a/drivers/soc/qcom/ramp_controller.c ++++ b/drivers/soc/qcom/ramp_controller.c +@@ -331,8 +331,8 @@ static struct platform_driver qcom_ramp_controller_driver = { + .of_match_table = qcom_ramp_controller_match_table, + .suppress_bind_attrs = true, + }, +- .probe = qcom_ramp_controller_probe, +- .remove_new = qcom_ramp_controller_remove, ++ .probe = qcom_ramp_controller_probe, ++ .remove = qcom_ramp_controller_remove, + }; + + static int __init qcom_ramp_controller_init(void) +diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c +index df850d0731022..33603b8fd8f38 100644 +--- a/drivers/soc/qcom/rmtfs_mem.c ++++ b/drivers/soc/qcom/rmtfs_mem.c +@@ -315,7 +315,7 @@ MODULE_DEVICE_TABLE(of, qcom_rmtfs_mem_of_match); + + static struct platform_driver qcom_rmtfs_mem_driver = { + .probe = qcom_rmtfs_mem_probe, +- .remove_new = qcom_rmtfs_mem_remove, ++ .remove = qcom_rmtfs_mem_remove, + .driver = { + .name = "qcom_rmtfs_mem", + .of_match_table = qcom_rmtfs_mem_of_match, +diff --git a/drivers/soc/qcom/rpm-proc.c b/drivers/soc/qcom/rpm-proc.c +index 2995d9b901903..2466d0400c2e9 100644 +--- a/drivers/soc/qcom/rpm-proc.c ++++ b/drivers/soc/qcom/rpm-proc.c +@@ -53,7 +53,7 @@ MODULE_DEVICE_TABLE(of, rpm_proc_of_match); + + static struct platform_driver rpm_proc_driver = { + .probe = rpm_proc_probe, +- .remove_new = rpm_proc_remove, ++ .remove = rpm_proc_remove, + .driver = { + .name = "qcom-rpm-proc", + .of_match_table = rpm_proc_of_match, +diff --git a/drivers/soc/qcom/rpm_master_stats.c b/drivers/soc/qcom/rpm_master_stats.c +index 086fe4ba6707f..49e4f94572792 100644 +--- a/drivers/soc/qcom/rpm_master_stats.c ++++ b/drivers/soc/qcom/rpm_master_stats.c +@@ -155,7 +155,7 @@ static const struct of_device_id rpm_master_table[] = { + + static struct platform_driver master_stats_driver = { + .probe = master_stats_probe, +- .remove_new = master_stats_remove, ++ .remove = master_stats_remove, + .driver = { + .name = "qcom_rpm_master_stats", + .of_match_table = rpm_master_table, +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index db77642776f93..56eea77395bf2 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1251,7 +1251,7 @@ MODULE_DEVICE_TABLE(of, qcom_smem_of_match); + + static struct platform_driver qcom_smem_driver = { + .probe = qcom_smem_probe, +- .remove_new = qcom_smem_remove, ++ .remove = qcom_smem_remove, + .driver = { + .name = "qcom-smem", + .of_match_table = qcom_smem_of_match, +diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c +index 95d8a8f728db5..801d25ff4d533 100644 +--- a/drivers/soc/qcom/smp2p.c ++++ b/drivers/soc/qcom/smp2p.c +@@ -698,7 +698,7 @@ MODULE_DEVICE_TABLE(of, qcom_smp2p_of_match); + + static struct platform_driver qcom_smp2p_driver = { + .probe = qcom_smp2p_probe, +- .remove_new = qcom_smp2p_remove, ++ .remove = qcom_smp2p_remove, + .driver = { + .name = "qcom_smp2p", + .of_match_table = qcom_smp2p_of_match, +diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c +index ffe78ae343864..e803ea342c971 100644 +--- a/drivers/soc/qcom/smsm.c ++++ b/drivers/soc/qcom/smsm.c +@@ -682,9 +682,9 @@ MODULE_DEVICE_TABLE(of, qcom_smsm_of_match); + + static struct platform_driver qcom_smsm_driver = { + .probe = qcom_smsm_probe, +- .remove_new = qcom_smsm_remove, +- .driver = { +- .name = "qcom-smsm", ++ .remove = qcom_smsm_remove, ++ .driver = { ++ .name = "qcom-smsm", + .of_match_table = qcom_smsm_of_match, + }, + }; +diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c +index c2f2a1ce4194b..416cf447630f4 100644 +--- a/drivers/soc/qcom/socinfo.c ++++ b/drivers/soc/qcom/socinfo.c +@@ -822,7 +822,7 @@ static void qcom_socinfo_remove(struct platform_device *pdev) + + static struct platform_driver qcom_socinfo_driver = { + .probe = qcom_socinfo_probe, +- .remove_new = qcom_socinfo_remove, ++ .remove = qcom_socinfo_remove, + .driver = { + .name = "qcom-socinfo", + }, +diff --git a/drivers/soc/rockchip/io-domain.c b/drivers/soc/rockchip/io-domain.c +index fd9fd31f71c25..f94985a905c29 100644 +--- a/drivers/soc/rockchip/io-domain.c ++++ b/drivers/soc/rockchip/io-domain.c +@@ -742,10 +742,10 @@ static void rockchip_iodomain_remove(struct platform_device *pdev) + } + + static struct platform_driver rockchip_iodomain_driver = { +- .probe = rockchip_iodomain_probe, +- .remove_new = rockchip_iodomain_remove, +- .driver = { +- .name = "rockchip-iodomain", ++ .probe = rockchip_iodomain_probe, ++ .remove = rockchip_iodomain_remove, ++ .driver = { ++ .name = "rockchip-iodomain", + .of_match_table = rockchip_iodomain_match, + }, + }; +diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c +index dedfe6d0fb3f3..9c4c74ced92e4 100644 +--- a/drivers/soc/samsung/exynos-chipid.c ++++ b/drivers/soc/samsung/exynos-chipid.c +@@ -198,8 +198,8 @@ static struct platform_driver exynos_chipid_driver = { + .name = "exynos-chipid", + .of_match_table = exynos_chipid_of_device_ids, + }, +- .probe = exynos_chipid_probe, +- .remove_new = exynos_chipid_remove, ++ .probe = exynos_chipid_probe, ++ .remove = exynos_chipid_remove, + }; + module_platform_driver(exynos_chipid_driver); + +diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c +index 9cbc562ae7d37..846b17ffc2f97 100644 +--- a/drivers/soc/tegra/cbb/tegra194-cbb.c ++++ b/drivers/soc/tegra/cbb/tegra194-cbb.c +@@ -2330,7 +2330,7 @@ static const struct dev_pm_ops tegra194_cbb_pm = { + + static struct platform_driver tegra194_cbb_driver = { + .probe = tegra194_cbb_probe, +- .remove_new = tegra194_cbb_remove, ++ .remove = tegra194_cbb_remove, + .driver = { + .name = "tegra194-cbb", + .of_match_table = of_match_ptr(tegra194_cbb_match), +diff --git a/drivers/soc/ti/k3-ringacc.c b/drivers/soc/ti/k3-ringacc.c +index 8c01029683515..82a15cad1c6c4 100644 +--- a/drivers/soc/ti/k3-ringacc.c ++++ b/drivers/soc/ti/k3-ringacc.c +@@ -1562,7 +1562,7 @@ static void k3_ringacc_remove(struct platform_device *pdev) + + static struct platform_driver k3_ringacc_driver = { + .probe = k3_ringacc_probe, +- .remove_new = k3_ringacc_remove, ++ .remove = k3_ringacc_remove, + .driver = { + .name = "k3-ringacc", + .of_match_table = k3_ringacc_of_match, +diff --git a/drivers/soc/ti/knav_dma.c b/drivers/soc/ti/knav_dma.c +index c9cf8a90c6d49..553ae7ee20f16 100644 +--- a/drivers/soc/ti/knav_dma.c ++++ b/drivers/soc/ti/knav_dma.c +@@ -783,8 +783,8 @@ MODULE_DEVICE_TABLE(of, of_match); + + static struct platform_driver knav_dma_driver = { + .probe = knav_dma_probe, +- .remove_new = knav_dma_remove, +- .driver = { ++ .remove = knav_dma_remove, ++ .driver = { + .name = "keystone-navigator-dma", + .of_match_table = of_match, + }, +diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c +index 6c98738e548a8..c2ad1863048fe 100644 +--- a/drivers/soc/ti/knav_qmss_queue.c ++++ b/drivers/soc/ti/knav_qmss_queue.c +@@ -1894,7 +1894,7 @@ static void knav_queue_remove(struct platform_device *pdev) + + static struct platform_driver keystone_qmss_driver = { + .probe = knav_queue_probe, +- .remove_new = knav_queue_remove, ++ .remove = knav_queue_remove, + .driver = { + .name = "keystone-navigator-qmss", + .of_match_table = keystone_qmss_of_match, +diff --git a/drivers/soc/ti/pm33xx.c b/drivers/soc/ti/pm33xx.c +index 8169885ab1e05..dfdff186c805c 100644 +--- a/drivers/soc/ti/pm33xx.c ++++ b/drivers/soc/ti/pm33xx.c +@@ -591,7 +591,7 @@ static struct platform_driver am33xx_pm_driver = { + .name = "pm33xx", + }, + .probe = am33xx_pm_probe, +- .remove_new = am33xx_pm_remove, ++ .remove = am33xx_pm_remove, + }; + module_platform_driver(am33xx_pm_driver); + +diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c +index f588153e8178d..038576805bfa0 100644 +--- a/drivers/soc/ti/pruss.c ++++ b/drivers/soc/ti/pruss.c +@@ -593,8 +593,8 @@ static struct platform_driver pruss_driver = { + .name = "pruss", + .of_match_table = pruss_of_match, + }, +- .probe = pruss_probe, +- .remove_new = pruss_remove, ++ .probe = pruss_probe, ++ .remove = pruss_remove, + }; + module_platform_driver(pruss_driver); + +diff --git a/drivers/soc/ti/smartreflex.c b/drivers/soc/ti/smartreflex.c +index 38add2ab56137..ced3a73929e3b 100644 +--- a/drivers/soc/ti/smartreflex.c ++++ b/drivers/soc/ti/smartreflex.c +@@ -969,7 +969,7 @@ MODULE_DEVICE_TABLE(of, omap_sr_match); + + static struct platform_driver smartreflex_driver = { + .probe = omap_sr_probe, +- .remove_new = omap_sr_remove, ++ .remove = omap_sr_remove, + .shutdown = omap_sr_shutdown, + .driver = { + .name = DRIVER_NAME, +diff --git a/drivers/soc/ti/wkup_m3_ipc.c b/drivers/soc/ti/wkup_m3_ipc.c +index 88f774db92084..79dde9a7ec639 100644 +--- a/drivers/soc/ti/wkup_m3_ipc.c ++++ b/drivers/soc/ti/wkup_m3_ipc.c +@@ -755,7 +755,7 @@ MODULE_DEVICE_TABLE(of, wkup_m3_ipc_of_match); + + static struct platform_driver wkup_m3_ipc_driver = { + .probe = wkup_m3_ipc_probe, +- .remove_new = wkup_m3_ipc_remove, ++ .remove = wkup_m3_ipc_remove, + .driver = { + .name = "wkup_m3_ipc", + .of_match_table = wkup_m3_ipc_of_match, +diff --git a/drivers/soc/xilinx/xlnx_event_manager.c b/drivers/soc/xilinx/xlnx_event_manager.c +index 85df6b9c04ee6..a572d15f61616 100644 +--- a/drivers/soc/xilinx/xlnx_event_manager.c ++++ b/drivers/soc/xilinx/xlnx_event_manager.c +@@ -711,7 +711,7 @@ static void xlnx_event_manager_remove(struct platform_device *pdev) + + static struct platform_driver xlnx_event_manager_driver = { + .probe = xlnx_event_manager_probe, +- .remove_new = xlnx_event_manager_remove, ++ .remove = xlnx_event_manager_remove, + .driver = { + .name = "xlnx_event_manager", + }, +diff --git a/drivers/soc/xilinx/zynqmp_power.c b/drivers/soc/xilinx/zynqmp_power.c +index 411d33f2fb053..ae59bf16659a6 100644 +--- a/drivers/soc/xilinx/zynqmp_power.c ++++ b/drivers/soc/xilinx/zynqmp_power.c +@@ -408,7 +408,7 @@ MODULE_DEVICE_TABLE(of, pm_of_match); + + static struct platform_driver zynqmp_pm_platform_driver = { + .probe = zynqmp_pm_probe, +- .remove_new = zynqmp_pm_remove, ++ .remove = zynqmp_pm_remove, + .driver = { + .name = "zynqmp_power", + .of_match_table = pm_of_match, +-- +2.51.0 + diff --git a/queue-6.12/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch b/queue-6.12/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch new file mode 100644 index 0000000000..1f31ce331d --- /dev/null +++ b/queue-6.12/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch @@ -0,0 +1,112 @@ +From e96dedea7ab9a9045ade244bfb2feb23e660219d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 02:40:45 +0300 +Subject: spi: airoha-snfi: en7523: workaround flash damaging if UART_TXD was + short to GND + +From: Mikhail Kshevetskiy + +[ Upstream commit 061795b345aff371df8f71d54ae7c7dc8ae630d0 ] + +Airoha EN7523 specific bug +-------------------------- +We found that some serial console may pull TX line to GROUND during board +boot time. Airoha uses TX line as one of its bootstrap pins. On the EN7523 +SoC this may lead to booting in RESERVED boot mode. + +It was found that some flashes operates incorrectly in RESERVED mode. +Micron and Skyhigh flashes are definitely affected by the issue, +Winbond flashes are not affected. + +Details: +-------- +DMA reading of odd pages on affected flashes operates incorrectly. Page +reading offset (start of the page) on hardware level is replaced by 0x10. +Thus results in incorrect data reading. As result OS loading becomes +impossible. + +Usage of UBI make things even worse. On attaching, UBI will detects +corruptions (because of wrong reading of odd pages) and will try to +recover. For recovering UBI will erase and write 'damaged' blocks with +a valid information. This will destroy all UBI data. + +Non-DMA reading is OK. + +This patch detects booting in reserved mode, turn off DMA and print big +fat warning. + +It's worth noting that the boot configuration is preserved across reboots. +Therefore, to boot normally, you should do the following: +- disconnect the serial console from the board, +- power cycle the board. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251125234047.1101985-2-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index b78163eaed61d..20b5d469d519a 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -1030,6 +1030,11 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = { + .dirmap_write = airoha_snand_dirmap_write, + }; + ++static const struct spi_controller_mem_ops airoha_snand_nodma_mem_ops = { ++ .supports_op = airoha_snand_supports_op, ++ .exec_op = airoha_snand_exec_op, ++}; ++ + static int airoha_snand_setup(struct spi_device *spi) + { + struct airoha_snand_ctrl *as_ctrl; +@@ -1104,7 +1109,9 @@ static int airoha_snand_probe(struct platform_device *pdev) + struct airoha_snand_ctrl *as_ctrl; + struct device *dev = &pdev->dev; + struct spi_controller *ctrl; ++ bool dma_enable = true; + void __iomem *base; ++ u32 sfc_strap; + int err; + + ctrl = devm_spi_alloc_host(dev, sizeof(*as_ctrl)); +@@ -1139,12 +1146,28 @@ static int airoha_snand_probe(struct platform_device *pdev) + return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk), + "unable to get spi clk\n"); + ++ if (device_is_compatible(dev, "airoha,en7523-snand")) { ++ err = regmap_read(as_ctrl->regmap_ctrl, ++ REG_SPI_CTRL_SFC_STRAP, &sfc_strap); ++ if (err) ++ return err; ++ ++ if (!(sfc_strap & 0x04)) { ++ dma_enable = false; ++ dev_warn(dev, "Detected booting in RESERVED mode (UART_TXD was short to GND).\n"); ++ dev_warn(dev, "This mode is known for incorrect DMA reading of some flashes.\n"); ++ dev_warn(dev, "Much slower PIO mode will be used to prevent flash data damage.\n"); ++ dev_warn(dev, "Unplug UART cable and power cycle board to get full performance.\n"); ++ } ++ } ++ + err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32)); + if (err) + return err; + + ctrl->num_chipselect = 2; +- ctrl->mem_ops = &airoha_snand_mem_ops; ++ ctrl->mem_ops = dma_enable ? &airoha_snand_mem_ops ++ : &airoha_snand_nodma_mem_ops; + ctrl->bits_per_word_mask = SPI_BPW_MASK(8); + ctrl->mode_bits = SPI_RX_DUAL; + ctrl->setup = airoha_snand_setup; +-- +2.51.0 + diff --git a/queue-6.12/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch b/queue-6.12/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch new file mode 100644 index 0000000000..8584c8a641 --- /dev/null +++ b/queue-6.12/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch @@ -0,0 +1,50 @@ +From 59973a72e4ffe1a70bda2ed40f8eb7040728d24a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 16:06:30 +0800 +Subject: spi: ch341: fix out-of-bounds memory access in ch341_transfer_one + +From: Tianchu Chen + +[ Upstream commit 545d1287e40a55242f6ab68bcc1ba3b74088b1bc ] + +Discovered by Atuin - Automated Vulnerability Discovery Engine. + +The 'len' variable is calculated as 'min(32, trans->len + 1)', +which includes the 1-byte command header. + +When copying data from 'trans->tx_buf' to 'ch341->tx_buf + 1', using 'len' +as the length is incorrect because: + +1. It causes an out-of-bounds read from 'trans->tx_buf' (which has size + 'trans->len', i.e., 'len - 1' in this context). +2. It can cause an out-of-bounds write to 'ch341->tx_buf' if 'len' is + CH341_PACKET_LENGTH (32). Writing 32 bytes to ch341->tx_buf + 1 + overflows the buffer. + +Fix this by copying 'len - 1' bytes. + +Fixes: 8846739f52af ("spi: add ch341a usb2spi driver") +Signed-off-by: Tianchu Chen +Link: https://patch.msgid.link/20251128160630.0f922c45ec6084a46fb57099@linux.dev +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-ch341.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c +index d2351812d310d..0db74e95552f9 100644 +--- a/drivers/spi/spi-ch341.c ++++ b/drivers/spi/spi-ch341.c +@@ -78,7 +78,7 @@ static int ch341_transfer_one(struct spi_controller *host, + + ch341->tx_buf[0] = CH341A_CMD_SPI_STREAM; + +- memcpy(ch341->tx_buf + 1, trans->tx_buf, len); ++ memcpy(ch341->tx_buf + 1, trans->tx_buf, len - 1); + + ret = usb_bulk_msg(ch341->udev, ch341->write_pipe, ch341->tx_buf, len, + NULL, CH341_DEFAULT_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.12/spi-tegra210-quad-fix-timeout-handling.patch b/queue-6.12/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..12549afb4b --- /dev/null +++ b/queue-6.12/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,117 @@ +From 0033b252d13b3012122e4c896254e99340ab7cbb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 92348ebc60c78..39aa0f1485686 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -999,8 +999,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1145,9 +1147,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1169,11 +1173,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + ret = 0; + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1257,6 +1263,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1353,6 +1361,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1436,6 +1445,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-6.12/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-6.12/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..1302bf96b8 --- /dev/null +++ b/queue-6.12/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From 2bfd16dc86029e5f91a8f36c61713ac69b50de79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 8fab5126765d4..69649c0ef8739 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1170,8 +1170,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-6.12/task_work-fix-nmi-race-condition.patch b/queue-6.12/task_work-fix-nmi-race-condition.patch new file mode 100644 index 0000000000..85fcd65dec --- /dev/null +++ b/queue-6.12/task_work-fix-nmi-race-condition.patch @@ -0,0 +1,62 @@ +From 0a4dbb82ca93a2d3ec7214bde91d0bc25753ed4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 15:47:00 +0200 +Subject: task_work: Fix NMI race condition + +From: Peter Zijlstra + +[ Upstream commit ef1ea98c8fffe227e5319215d84a53fa2a4bcebc ] + + __schedule() + // disable irqs + + task_work_add(current, work, TWA_NMI_CURRENT); + + // current = next; + // enable irqs + + task_work_set_notify_irq() + test_and_set_tsk_thread_flag(current, + TIF_NOTIFY_RESUME); // wrong task! + + // original task skips task work on its next return to user (or exit!) + +Fixes: 466e4d801cd4 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode.") +Reported-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Steven Rostedt (Google) +Link: https://patch.msgid.link/20250924080118.425949403@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/task_work.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/task_work.c b/kernel/task_work.c +index c969f1f26be58..48ab6275e6e7e 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -9,7 +9,12 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ + #ifdef CONFIG_IRQ_WORK + static void task_work_set_notify_irq(struct irq_work *entry) + { +- test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); ++ /* ++ * no-op IPI ++ * ++ * TWA_NMI_CURRENT will already have set the TIF flag, all ++ * this interrupt does it tickle the return-to-user path. ++ */ + } + static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = + IRQ_WORK_INIT_HARD(task_work_set_notify_irq); +@@ -98,6 +103,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, + break; + #ifdef CONFIG_IRQ_WORK + case TWA_NMI_CURRENT: ++ set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); + irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); + break; + #endif +-- +2.51.0 + diff --git a/queue-6.12/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch b/queue-6.12/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch new file mode 100644 index 0000000000..fa244a667d --- /dev/null +++ b/queue-6.12/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch @@ -0,0 +1,43 @@ +From 89aa87e46b716e356b24ad1f9b1ebc6db458150d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:50 +0200 +Subject: tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit c485ca3aff2442adea4c08ceb5183e671ebed22a ] + +There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, +simply print the message with "unknown error" rather than the integer +value of errno. + +Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/stdio.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h +index c968dbbc4ef81..4749a32b3064b 100644 +--- a/tools/include/nolibc/stdio.h ++++ b/tools/include/nolibc/stdio.h +@@ -351,7 +351,11 @@ int printf(const char *fmt, ...) + static __attribute__((unused)) + void perror(const char *msg) + { ++#ifdef NOLIBC_IGNORE_ERRNO ++ fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); ++#else + fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); ++#endif + } + + static __attribute__((unused)) +-- +2.51.0 + diff --git a/queue-6.12/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch b/queue-6.12/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch new file mode 100644 index 0000000000..dd86624f27 --- /dev/null +++ b/queue-6.12/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch @@ -0,0 +1,45 @@ +From 28540ba8a1028f5aacf5f3a6e37f96b3efa2533b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 18:13:48 -0400 +Subject: tracefs: fix a leak in eventfs_create_events_dir() + +From: Al Viro + +[ Upstream commit 798a401660a151633cb171738a72a8f1efb9b0b4 ] + +If we have LOCKDOWN_TRACEFS, the function bails out - *after* +having locked the parent directory and without bothering to +undo that. Just check it before tracefs_start_creating()... + +Fixes: e24709454c45 "tracefs/eventfs: Add missing lockdown checks" +Acked-by: Steven Rostedt (Google) +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/tracefs/event_inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index 8705c77a9e75a..93c231601c8e2 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -757,7 +757,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + const struct eventfs_entry *entries, + int size, void *data) + { +- struct dentry *dentry = tracefs_start_creating(name, parent); ++ struct dentry *dentry; + struct eventfs_root_inode *rei; + struct eventfs_inode *ei; + struct tracefs_inode *ti; +@@ -768,6 +768,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + ++ dentry = tracefs_start_creating(name, parent); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + +-- +2.51.0 + diff --git a/queue-6.12/ublk-prevent-invalid-access-with-debug.patch b/queue-6.12/ublk-prevent-invalid-access-with-debug.patch new file mode 100644 index 0000000000..e5f06f308f --- /dev/null +++ b/queue-6.12/ublk-prevent-invalid-access-with-debug.patch @@ -0,0 +1,57 @@ +From 9648d4cf2a396ca6aca2a8b0a6055db37ea5055f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 12:48:35 +0000 +Subject: ublk: prevent invalid access with DEBUG + +From: Kevin Brodsky + +[ Upstream commit c6a45ee7607de3a350008630f4369b1b5ac80884 ] + +ublk_ch_uring_cmd_local() may jump to the out label before +initialising the io pointer. This will cause trouble if DEBUG is +defined, because the pr_devel() call dereferences io. Clang reports: + +drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] + 2403 | if (tag >= ub->dev_info.queue_depth) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here + 2492 | __func__, cmd_op, tag, ret, io->flags); + | + +Fix this by initialising io to NULL and checking it before +dereferencing it. + +Signed-off-by: Kevin Brodsky +Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") +Reviewed-by: Caleb Sander Mateos +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index defcc964ecab6..b874cb84bad95 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -1768,7 +1768,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + { + struct ublk_device *ub = cmd->file->private_data; + struct ublk_queue *ubq; +- struct ublk_io *io; ++ struct ublk_io *io = NULL; + u32 cmd_op = cmd->cmd_op; + unsigned tag = ub_cmd->tag; + int ret = -EINVAL; +@@ -1882,7 +1882,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + + out: + pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", +- __func__, cmd_op, tag, ret, io->flags); ++ __func__, cmd_op, tag, ret, io ? io->flags : 0); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.12/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-6.12/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..08a17e76d2 --- /dev/null +++ b/queue-6.12/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From b949fefc993e5a50a820a33e4652ec9be221b504 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 496caff66e7ea..dcf08042e894b 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-6.12/um-don-t-rename-vmap-to-kernel_vmap.patch b/queue-6.12/um-don-t-rename-vmap-to-kernel_vmap.patch new file mode 100644 index 0000000000..17da406c3e --- /dev/null +++ b/queue-6.12/um-don-t-rename-vmap-to-kernel_vmap.patch @@ -0,0 +1,70 @@ +From ae95e7698d0481ed362825bdfa89f6d42f685fde Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 16:32:12 +0800 +Subject: um: Don't rename vmap to kernel_vmap + +From: David Gow + +[ Upstream commit a74b6c0e53a6df8e8a096b50c06c4f872906368a ] + +In order to work around the existence of a vmap symbol in libpcap, the +UML makefile unconditionally redefines vmap to kernel_vmap. However, +this not only affects the actual vmap symbol, but also anything else +named vmap, including a number of struct members in DRM. + +This would not be too much of a problem, since all uses are also +updated, except we now have Rust DRM bindings, which expect the +corresponding Rust structs to have 'vmap' names. Since the redefinition +applies in bindgen, but not to Rust code, we end up with errors such as: + +error[E0560]: struct `drm_gem_object_funcs` has no fields named `vmap` + --> rust/kernel/drm/gem/mod.rs:210:9 + +Since libpcap support was removed in commit 12b8e7e69aa7 ("um: Remove +obsolete pcap driver"), remove the, now unnecessary, define as well. + +We also take this opportunity to update the comment. + +Signed-off-by: David Gow +Acked-by: Miguel Ojeda +Link: https://patch.msgid.link/20251122083213.3996586-1-davidgow@google.com +Fixes: 12b8e7e69aa7 ("um: Remove obsolete pcap driver") +[adjust commmit message a bit] +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/Makefile | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/arch/um/Makefile b/arch/um/Makefile +index 3317d87e20920..f3f8c3ab4bfb6 100644 +--- a/arch/um/Makefile ++++ b/arch/um/Makefile +@@ -46,19 +46,17 @@ ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) + ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared + KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um + +-# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so +-# named - it's a common symbol in libpcap, so we get a binary which crashes. +-# +-# Same things for in6addr_loopback and mktime - found in libc. For these two we +-# only get link-time error, luckily. ++# -Dstrrchr=kernel_strrchr (as well as the various in6addr symbols) prevents ++# anything from referencing ++# libc symbols with the same name, which can cause a linker error. + # + # -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a + # embedded copy of longjmp, same thing for setjmp. + # +-# These apply to USER_CFLAGS to. ++# These apply to USER_CFLAGS too. + + KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ +- $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ ++ $(ARCH_INCLUDE) $(MODE_INCLUDE) \ + -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ + -Din6addr_loopback=kernel_in6addr_loopback \ + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr +-- +2.51.0 + diff --git a/queue-6.12/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-6.12/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..bb9dd5af9e --- /dev/null +++ b/queue-6.12/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From 4190970787fa303d039fcd4c5a48e336bf51ad0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 225863321dc47..45cff32656c6e 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-6.12/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch b/queue-6.12/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch new file mode 100644 index 0000000000..db79f50c02 --- /dev/null +++ b/queue-6.12/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch @@ -0,0 +1,45 @@ +From 59d6279024e7c2495bf0b17d922c00ab053b10f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Jun 2025 17:46:55 +0800 +Subject: usb: dwc2: disable platform lowlevel hw resources during shutdown + +From: Jisheng Zhang + +[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ] + +On some SoC platforms, in shutdown stage, most components' power is cut +off, but there's still power supply to the so called always-on +domain, so if the dwc2's regulator is from the always-on domain, we +need to explicitly disable it to save power. + +Disable platform lowlevel hw resources such as phy, clock and +regulators etc. in device shutdown hook to reduce non-necessary power +consumption when the platform enters shutdown stage. + +Signed-off-by: Jisheng Zhang +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index c1b7209b94836..79ce88b5f07d9 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -371,6 +371,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); ++ ++ if (hsotg->ll_hw_enabled) ++ dwc2_lowlevel_hw_disable(hsotg); + } + + /** +-- +2.51.0 + diff --git a/queue-6.12/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-6.12/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..3d7846f66d --- /dev/null +++ b/queue-6.12/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From fc5f1681f74d07c885e326a53a3740c9e2a989a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 79ce88b5f07d9..fad6f68f86bd6 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-6.12/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-6.12/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..db3513dbb0 --- /dev/null +++ b/queue-6.12/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From 1e8afe99fd28f8072d9eb8ed55f5fbb2be929be8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index fad6f68f86bd6..e80982c817d7d 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -702,6 +706,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-6.12/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-6.12/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..730afd3b14 --- /dev/null +++ b/queue-6.12/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From e5264a9c75e089f91e1725c50bf971f616c0272d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index d2b2787be4092..6138468c67c47 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2431,7 +2431,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-6.12/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-6.12/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..e236ae8770 --- /dev/null +++ b/queue-6.12/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 5ef3b8ad98b12c21f78e076ca8bfa849fbc5952b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index c713a9854a3e5..3ffee64a63a24 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-6.12/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch b/queue-6.12/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch new file mode 100644 index 0000000000..7e9432a2ab --- /dev/null +++ b/queue-6.12/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch @@ -0,0 +1,49 @@ +From 24ea1132d43490eed42ca851a38b2df7ffde1bab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 06:42:53 -0700 +Subject: vdpa/mlx5: Fix incorrect error code reporting in query_virtqueues + +From: Alok Tiwari + +[ Upstream commit f0ea2e91093ac979d07ebd033e0f45869b1d2608 ] + +When query_virtqueues() fails, the error log prints the variable err +instead of cmd->err. Since err may still be zero at this point, the +log message can misleadingly report a success value 0 even though the +command actually failed. + +Even worse, once err is set to the first failure, subsequent logs +print that same stale value. This makes the error reporting appear +one step behind the actual failing queue index, which is confusing +and misleading. + +Fix the log to report cmd->err, which reflects the real failure code +returned by the firmware. + +Fixes: 1fcdf43ea69e ("vdpa/mlx5: Use async API for vq query command") +Signed-off-by: Alok Tiwari +Acked-by: Jason Wang +Reviewed-by: Dragos Tatulea +Signed-off-by: Michael S. Tsirkin +Message-Id: <20250929134258.80956-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index 2e0b8c5bec8d2..51b2485e874f4 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -1258,7 +1258,7 @@ static int query_virtqueues(struct mlx5_vdpa_net *ndev, + int vq_idx = start_vq + i; + + if (cmd->err) { +- mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, err); ++ mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, cmd->err); + if (!err) + err = cmd->err; + continue; +-- +2.51.0 + diff --git a/queue-6.12/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch b/queue-6.12/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch new file mode 100644 index 0000000000..aa947466ee --- /dev/null +++ b/queue-6.12/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch @@ -0,0 +1,40 @@ +From de92c198480df680dfe644a9d0fe502af25f1a0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 10:46:46 -0700 +Subject: vdpa/pds: use %pe for ERR_PTR() in event handler registration + +From: Alok Tiwari + +[ Upstream commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 ] + +Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended +for string pointers, while %pe correctly prints symbolic error names +for error pointers returned via ERR_PTR(). +This shows the returned error value more clearly. + +Fixes: 67f27b8b3a34 ("pds_vdpa: subscribe to the pds_core events") +Signed-off-by: Alok Tiwari +Reviewed-by: Brett Creeley +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251018174705.1511982-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/pds/vdpa_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c +index 301d95e085960..a1eff7441450c 100644 +--- a/drivers/vdpa/pds/vdpa_dev.c ++++ b/drivers/vdpa/pds/vdpa_dev.c +@@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) + err = pdsc_register_notify(nb); + if (err) { + nb->notifier_call = NULL; +- dev_err(dev, "failed to register pds event handler: %ps\n", ++ dev_err(dev, "failed to register pds event handler: %pe\n", + ERR_PTR(err)); + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.12/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch b/queue-6.12/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch new file mode 100644 index 0000000000..f547505f83 --- /dev/null +++ b/queue-6.12/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch @@ -0,0 +1,305 @@ +From b7b3887c7e9c0dd375cbb0e1b6b383444c2d1c79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:36:22 -0700 +Subject: vfio/pci: Use RCU for error/request triggers to avoid circular + locking + +From: Alex Williamson + +[ Upstream commit 98693e0897f754e3f51ce6626ed5f785f625ba2b ] + +Thanks to a device generating an ACS violation during bus reset, +lockdep reported the following circular locking issue: + +CPU0: SET_IRQS (MSI/X): holds igate, acquires memory_lock +CPU1: HOT_RESET: holds memory_lock, acquires pci_bus_sem +CPU2: AER: holds pci_bus_sem, acquires igate + +This results in a potential 3-way deadlock. + +Remove the pci_bus_sem->igate leg of the triangle by using RCU +to peek at the eventfd rather than locking it with igate. + +Fixes: 3be3a074cf5b ("vfio-pci: Don't use device_lock around AER interrupt setup") +Signed-off-by: Alex Williamson +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20251124223623.2770706-1-alex@shazbot.org +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci_core.c | 68 ++++++++++++++++++++++--------- + drivers/vfio/pci/vfio_pci_intrs.c | 52 ++++++++++++++--------- + drivers/vfio/pci/vfio_pci_priv.h | 4 ++ + include/linux/vfio_pci_core.h | 10 ++++- + 4 files changed, 93 insertions(+), 41 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c +index 595503fa9ca89..c7ea0b23924af 100644 +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -42,6 +42,40 @@ static bool nointxmask; + static bool disable_vga; + static bool disable_idle_d3; + ++static void vfio_pci_eventfd_rcu_free(struct rcu_head *rcu) ++{ ++ struct vfio_pci_eventfd *eventfd = ++ container_of(rcu, struct vfio_pci_eventfd, rcu); ++ ++ eventfd_ctx_put(eventfd->ctx); ++ kfree(eventfd); ++} ++ ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx) ++{ ++ struct vfio_pci_eventfd *new = NULL; ++ struct vfio_pci_eventfd *old; ++ ++ lockdep_assert_held(&vdev->igate); ++ ++ if (ctx) { ++ new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); ++ if (!new) ++ return -ENOMEM; ++ ++ new->ctx = ctx; ++ } ++ ++ old = rcu_replace_pointer(*peventfd, new, ++ lockdep_is_held(&vdev->igate)); ++ if (old) ++ call_rcu(&old->rcu, vfio_pci_eventfd_rcu_free); ++ ++ return 0; ++} ++ + /* List of PF's that vfio_pci_core_sriov_configure() has been called on */ + static DEFINE_MUTEX(vfio_pci_sriov_pfs_mutex); + static LIST_HEAD(vfio_pci_sriov_pfs); +@@ -697,14 +731,8 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) + vfio_pci_core_disable(vdev); + + mutex_lock(&vdev->igate); +- if (vdev->err_trigger) { +- eventfd_ctx_put(vdev->err_trigger); +- vdev->err_trigger = NULL; +- } +- if (vdev->req_trigger) { +- eventfd_ctx_put(vdev->req_trigger); +- vdev->req_trigger = NULL; +- } ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->err_trigger, NULL); ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->req_trigger, NULL); + mutex_unlock(&vdev->igate); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_close_device); +@@ -1807,21 +1835,21 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count) + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + struct pci_dev *pdev = vdev->pdev; ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->req_trigger) { ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->req_trigger); ++ if (eventfd) { + if (!(count % 10)) + pci_notice_ratelimited(pdev, + "Relaying device request to user (#%u)\n", + count); +- eventfd_signal(vdev->req_trigger); ++ eventfd_signal(eventfd->ctx); + } else if (count == 0) { + pci_warn(pdev, + "No device request channel registered, blocked until released by user\n"); + } +- +- mutex_unlock(&vdev->igate); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_request); + +@@ -2228,13 +2256,13 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) + { + struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->err_trigger) +- eventfd_signal(vdev->err_trigger); +- +- mutex_unlock(&vdev->igate); ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->err_trigger); ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ rcu_read_unlock(); + + return PCI_ERS_RESULT_CAN_RECOVER; + } +diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c +index b2cf1af7fb0c7..ed86747749e53 100644 +--- a/drivers/vfio/pci/vfio_pci_intrs.c ++++ b/drivers/vfio/pci/vfio_pci_intrs.c +@@ -735,21 +735,27 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_core_device *vdev, + return 0; + } + +-static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, ++static int vfio_pci_set_ctx_trigger_single(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, + unsigned int count, uint32_t flags, + void *data) + { + /* DATA_NONE/DATA_BOOL enables loopback testing */ + if (flags & VFIO_IRQ_SET_DATA_NONE) { +- if (*ctx) { +- if (count) { +- eventfd_signal(*ctx); +- } else { +- eventfd_ctx_put(*ctx); +- *ctx = NULL; +- } ++ struct vfio_pci_eventfd *eventfd; ++ ++ eventfd = rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (!eventfd) ++ return -EINVAL; ++ ++ if (count) { ++ eventfd_signal(eventfd->ctx); + return 0; + } ++ ++ return vfio_pci_eventfd_replace_locked(vdev, peventfd, NULL); + } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { + uint8_t trigger; + +@@ -757,8 +763,15 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + return -EINVAL; + + trigger = *(uint8_t *)data; +- if (trigger && *ctx) +- eventfd_signal(*ctx); ++ ++ if (trigger) { ++ struct vfio_pci_eventfd *eventfd = ++ rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ } + + return 0; + } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { +@@ -769,22 +782,23 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + + fd = *(int32_t *)data; + if (fd == -1) { +- if (*ctx) +- eventfd_ctx_put(*ctx); +- *ctx = NULL; ++ return vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, NULL); + } else if (fd >= 0) { + struct eventfd_ctx *efdctx; ++ int ret; + + efdctx = eventfd_ctx_fdget(fd); + if (IS_ERR(efdctx)) + return PTR_ERR(efdctx); + +- if (*ctx) +- eventfd_ctx_put(*ctx); ++ ret = vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, efdctx); ++ if (ret) ++ eventfd_ctx_put(efdctx); + +- *ctx = efdctx; ++ return ret; + } +- return 0; + } + + return -EINVAL; +@@ -797,7 +811,7 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_ERR_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->err_trigger, + count, flags, data); + } + +@@ -808,7 +822,7 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->req_trigger, + count, flags, data); + } + +diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h +index 5e4fa69aee16c..cf5e42fca27e7 100644 +--- a/drivers/vfio/pci/vfio_pci_priv.h ++++ b/drivers/vfio/pci/vfio_pci_priv.h +@@ -26,6 +26,10 @@ struct vfio_pci_ioeventfd { + bool vfio_pci_intx_mask(struct vfio_pci_core_device *vdev); + void vfio_pci_intx_unmask(struct vfio_pci_core_device *vdev); + ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx); ++ + int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags, + unsigned index, unsigned start, unsigned count, + void *data); +diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h +index fbb472dd99b36..99da27c032d70 100644 +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,6 +28,11 @@ + struct vfio_pci_core_device; + struct vfio_pci_region; + ++struct vfio_pci_eventfd { ++ struct eventfd_ctx *ctx; ++ struct rcu_head rcu; ++}; ++ + struct vfio_pci_regops { + ssize_t (*rw)(struct vfio_pci_core_device *vdev, char __user *buf, + size_t count, loff_t *ppos, bool iswrite); +@@ -83,8 +89,8 @@ struct vfio_pci_core_device { + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; + int ioeventfds_nr; +- struct eventfd_ctx *err_trigger; +- struct eventfd_ctx *req_trigger; ++ struct vfio_pci_eventfd __rcu *err_trigger; ++ struct vfio_pci_eventfd __rcu *req_trigger; + struct eventfd_ctx *pm_wake_eventfd_ctx; + struct list_head dummy_resources_list; + struct mutex ioeventfds_lock; +-- +2.51.0 + diff --git a/queue-6.12/vhost-fix-kthread-worker-cgroup-failure-handling.patch b/queue-6.12/vhost-fix-kthread-worker-cgroup-failure-handling.patch new file mode 100644 index 0000000000..966e228eac --- /dev/null +++ b/queue-6.12/vhost-fix-kthread-worker-cgroup-failure-handling.patch @@ -0,0 +1,45 @@ +From 9816a77f81620279ed3953fe90062ad819219658 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 14:43:58 -0500 +Subject: vhost: Fix kthread worker cgroup failure handling + +From: Mike Christie + +[ Upstream commit f3f64c2eaffbc3169bbe1e5d1e897e6dacc839d1 ] + +If we fail to attach to a cgroup we are leaking the id. This adds +a new goto to free the id. + +Fixes: 7d9896e9f6d0 ("vhost: Reintroduce kthread API and add mode selection") +Signed-off-by: Mike Christie +Acked-by: Jason Wang +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251101194358.13605-1-michael.christie@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vhost/vhost.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index 71604668e53f6..276dded52212c 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -798,11 +798,13 @@ static int vhost_kthread_worker_create(struct vhost_worker *worker, + + ret = vhost_attach_task_to_cgroups(worker); + if (ret) +- goto stop_worker; ++ goto free_id; + + worker->id = id; + return 0; + ++free_id: ++ xa_erase(&dev->worker_xa, id); + stop_worker: + vhost_kthread_do_stop(worker); + return ret; +-- +2.51.0 + diff --git a/queue-6.12/virtio-fix-grammar-in-virtio_queue_info-docs.patch b/queue-6.12/virtio-fix-grammar-in-virtio_queue_info-docs.patch new file mode 100644 index 0000000000..f4ffe92d81 --- /dev/null +++ b/queue-6.12/virtio-fix-grammar-in-virtio_queue_info-docs.patch @@ -0,0 +1,36 @@ +From 6de46fe7f33bd99cf543faccf0cf4721a167201c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:36 -0500 +Subject: virtio: fix grammar in virtio_queue_info docs + +From: Michael S. Tsirkin + +[ Upstream commit 63598fba55ab9d384818fed48dc04006cecf7be4 ] + +Fix grammar in the description of @ctx + +Fixes: c502eb85c34e ("virtio: introduce virtio_queue_info struct and find_vqs_info() config op") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 8189f859231cc..1255493b7f377 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -24,7 +24,7 @@ typedef void vq_callback_t(struct virtqueue *); + * a virtqueue unused by the driver. + * @callback: A callback to invoke on a used buffer notification. + * NULL for a virtqueue that does not need a callback. +- * @ctx: A flag to indicate to maintain an extra context per virtqueue. ++ * @ctx: whether to maintain an extra context per virtqueue. + */ + struct virtqueue_info { + const char *name; +-- +2.51.0 + diff --git a/queue-6.12/virtio-fix-typo-in-virtio_device_ready-comment.patch b/queue-6.12/virtio-fix-typo-in-virtio_device_ready-comment.patch new file mode 100644 index 0000000000..b16245b91b --- /dev/null +++ b/queue-6.12/virtio-fix-typo-in-virtio_device_ready-comment.patch @@ -0,0 +1,36 @@ +From 7354caf2005222cc327f93b3be0d2aa51ef7d4c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:31 -0500 +Subject: virtio: fix typo in virtio_device_ready() comment + +From: Michael S. Tsirkin + +[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ] + +"coherenct" -> "coherent" + +Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 169c7d367facb..165f71635cb99 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -290,7 +290,7 @@ void virtio_device_ready(struct virtio_device *dev) + * specific set_status() method. + * + * A well behaved device will only notify a virtqueue after +- * DRIVER_OK, this means the device should "see" the coherenct ++ * DRIVER_OK, this means the device should "see" the coherent + * memory write that set vq->broken as false which is done by + * the driver when it sees DRIVER_OK, then the following + * driver's vring_interrupt() will see vq->broken as false so +-- +2.51.0 + diff --git a/queue-6.12/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-6.12/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..f04b3bdf2c --- /dev/null +++ b/queue-6.12/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From 3cef8f0958938e19e98af47c3a7783a2254bd56f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 1255493b7f377..94b3adc7c2dbf 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -312,7 +312,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu_mask: the cpu mask + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-6.12/virtio-fix-whitespace-in-virtio_config_ops.patch b/queue-6.12/virtio-fix-whitespace-in-virtio_config_ops.patch new file mode 100644 index 0000000000..8346bd07a3 --- /dev/null +++ b/queue-6.12/virtio-fix-whitespace-in-virtio_config_ops.patch @@ -0,0 +1,37 @@ +From 770fae6afdf8002a005c4856da27261e6c9e79bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:34 -0500 +Subject: virtio: fix whitespace in virtio_config_ops + +From: Michael S. Tsirkin + +[ Upstream commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 ] + +The finalize_features documentation uses a tab between words. +Use space instead. + +Fixes: d16c0cd27331 ("docs: driver-api: virtio: virtio on Linux") +Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com> +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 165f71635cb99..8189f859231cc 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -82,7 +82,7 @@ struct virtqueue_info { + * vdev: the virtio_device + * This sends the driver feature bits to the device: it can change + * the dev->feature bits if it wants. +- * Note that despite the name this can be called any number of ++ * Note that despite the name this can be called any number of + * times. + * Returns 0 on success or error status + * @bus_name: return the bus name associated with the device (optional) +-- +2.51.0 + diff --git a/queue-6.12/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-6.12/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..9a63b42109 --- /dev/null +++ b/queue-6.12/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From cbcb3fe8c300d6f5acc737fe2e956c3d48caa6b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index 7364bd53e38dd..bf62712bdbee8 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -93,7 +93,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-6.12/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch b/queue-6.12/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch new file mode 100644 index 0000000000..59c33c530a --- /dev/null +++ b/queue-6.12/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch @@ -0,0 +1,51 @@ +From ad9f75c916f7a96f23d683625e16700127dfa0c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 16:42:20 +0800 +Subject: watchdog: starfive: Fix resource leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 5bcc5786a0cfa9249ccbe539833040a6285d0de3 ] + +If pm_runtime_put_sync() fails after watchdog_register_device() +succeeds, the probe function jumps to err_exit without +unregistering the watchdog device. This leaves the watchdog +registered in the subsystem while the driver fails to load, +resulting in a resource leak. + +Add a new error label err_unregister_wdt to properly unregister +the watchdog device. + +Fixes: 8bc22a2f1bf0 ("watchdog: starfive: Check pm_runtime_enabled() before decrementing usage counter") +Signed-off-by: Haotian Zhang +Reviewed-by: Wim Van Sebroeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/starfive-wdt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c +index 19a2620d3d389..763b11b6f402c 100644 +--- a/drivers/watchdog/starfive-wdt.c ++++ b/drivers/watchdog/starfive-wdt.c +@@ -500,12 +500,14 @@ static int starfive_wdt_probe(struct platform_device *pdev) + if (pm_runtime_enabled(&pdev->dev)) { + ret = pm_runtime_put_sync(&pdev->dev); + if (ret) +- goto err_exit; ++ goto err_unregister_wdt; + } + } + + return 0; + ++err_unregister_wdt: ++ watchdog_unregister_device(&wdt->wdd); + err_exit: + starfive_wdt_disable_clock(wdt); + pm_runtime_disable(&pdev->dev); +-- +2.51.0 + diff --git a/queue-6.12/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-6.12/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..3cdbdc2fb1 --- /dev/null +++ b/queue-6.12/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From 2b8dcdfe0558c2667cacde8d41bf7f2f24d42546 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 650fdc7996e1c..dd3c2d69c9df1 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -326,19 +326,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); +@@ -355,15 +363,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -385,8 +398,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -417,7 +432,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -425,8 +441,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -443,7 +461,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -460,12 +478,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + static int wdat_wdt_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath10k-add-missing-include-of-export.h.patch b/queue-6.12/wifi-ath10k-add-missing-include-of-export.h.patch new file mode 100644 index 0000000000..8cc2dc87b4 --- /dev/null +++ b/queue-6.12/wifi-ath10k-add-missing-include-of-export.h.patch @@ -0,0 +1,201 @@ +From 632461103610a28a8e5ed9b709ebee585d5c4ab9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 09:13:56 -0700 +Subject: wifi: ath10k: Add missing include of export.h + +From: Jeff Johnson + +[ Upstream commit 32c3a0f8894311c743b2a6a15b50b13d01411ce1 ] + +Commit a934a57a42f6 ("scripts/misc-check: check missing #include + when W=1") introduced a new check that is producing +the following warnings: + +drivers/net/wireless/ath/ath10k/bmi.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/ce.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/core.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/coredump.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/debug.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/htc.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/htt_rx.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/htt_tx.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/mac.c: warning: EXPORT_SYMBOL() is used, but #include is missing +drivers/net/wireless/ath/ath10k/trace.c: warning: EXPORT_SYMBOL() is used, but #include is missing + +Add the missing #include to satisfy the check. + +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250611-ath-unused-export-v1-3-c36819df7e7b@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Stable-dep-of: f35a07a4842a ("wifi: ath10k: move recovery check logic into a new work") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/bmi.c | 2 ++ + drivers/net/wireless/ath/ath10k/ce.c | 2 ++ + drivers/net/wireless/ath/ath10k/core.c | 2 ++ + drivers/net/wireless/ath/ath10k/coredump.c | 2 ++ + drivers/net/wireless/ath/ath10k/debug.c | 2 ++ + drivers/net/wireless/ath/ath10k/htc.c | 3 +++ + drivers/net/wireless/ath/ath10k/htt_rx.c | 3 +++ + drivers/net/wireless/ath/ath10k/htt_tx.c | 2 ++ + drivers/net/wireless/ath/ath10k/mac.c | 1 + + drivers/net/wireless/ath/ath10k/trace.c | 2 ++ + 10 files changed, 21 insertions(+) + +diff --git a/drivers/net/wireless/ath/ath10k/bmi.c b/drivers/net/wireless/ath/ath10k/bmi.c +index 9a4f8e815412c..6f4ac47d0e6f2 100644 +--- a/drivers/net/wireless/ath/ath10k/bmi.c ++++ b/drivers/net/wireless/ath/ath10k/bmi.c +@@ -3,8 +3,10 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include + #include "bmi.h" + #include "hif.h" + #include "debug.h" +diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c +index afae4a8027f83..ac7a470fc3e1f 100644 +--- a/drivers/net/wireless/ath/ath10k/ce.c ++++ b/drivers/net/wireless/ath/ath10k/ce.c +@@ -4,8 +4,10 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include + #include "hif.h" + #include "ce.h" + #include "debug.h" +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 7b6812909ab31..d13acb9e70009 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -4,8 +4,10 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include + #include + #include + #include +diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c +index bb3a276b7ed58..50d0c4213ecfd 100644 +--- a/drivers/net/wireless/ath/ath10k/coredump.c ++++ b/drivers/net/wireless/ath/ath10k/coredump.c +@@ -3,11 +3,13 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include "coredump.h" + + #include ++#include + #include + #include + #include +diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c +index 35bfe7232e95e..e45ea59e3e42d 100644 +--- a/drivers/net/wireless/ath/ath10k/debug.c ++++ b/drivers/net/wireless/ath/ath10k/debug.c +@@ -4,10 +4,12 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, 2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include + #include ++#include + #include + #include + #include +diff --git a/drivers/net/wireless/ath/ath10k/htc.c b/drivers/net/wireless/ath/ath10k/htc.c +index a6e21ce90bad6..cd0917d3ef0e0 100644 +--- a/drivers/net/wireless/ath/ath10k/htc.c ++++ b/drivers/net/wireless/ath/ath10k/htc.c +@@ -3,8 +3,11 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include ++ + #include "core.h" + #include "hif.h" + #include "debug.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c +index 7d28ae5453cf8..42b75961cb962 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_rx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c +@@ -4,8 +4,11 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include ++ + #include "core.h" + #include "htc.h" + #include "htt.h" +diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c +index 9725feecefd6f..c1ddd761af3e9 100644 +--- a/drivers/net/wireless/ath/ath10k/htt_tx.c ++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c +@@ -3,8 +3,10 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include + #include + #include "htt.h" + #include "mac.h" +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 68d049289359b..935923c290e1f 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -9,6 +9,7 @@ + + #include "mac.h" + ++#include + #include + #include + #include +diff --git a/drivers/net/wireless/ath/ath10k/trace.c b/drivers/net/wireless/ath/ath10k/trace.c +index c7d4c97e6079f..421ec47c59bdf 100644 +--- a/drivers/net/wireless/ath/ath10k/trace.c ++++ b/drivers/net/wireless/ath/ath10k/trace.c +@@ -1,8 +1,10 @@ + // SPDX-License-Identifier: ISC + /* + * Copyright (c) 2012 Qualcomm Atheros, Inc. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + ++#include + #include + + #define CREATE_TRACE_POINTS +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath10k-avoid-vdev-delete-timeout-when-firmware-.patch b/queue-6.12/wifi-ath10k-avoid-vdev-delete-timeout-when-firmware-.patch new file mode 100644 index 0000000000..79fae5bb35 --- /dev/null +++ b/queue-6.12/wifi-ath10k-avoid-vdev-delete-timeout-when-firmware-.patch @@ -0,0 +1,106 @@ +From bc783e43ddc75a9677f0b05f098e83787602d96f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 May 2025 15:17:04 +0200 +Subject: wifi: ath10k: Avoid vdev delete timeout when firmware is already down + +From: Loic Poulain + +[ Upstream commit dc9c4252fe0d7a7f1ee904405ea91534277305bf ] + +In some scenarios, the firmware may be stopped before the interface is +removed, either due to a crash or because the remoteproc (e.g., MPSS) +is shut down early during system reboot or shutdown. + +This leads to a delay during interface teardown, as the driver waits for +a vdev delete response that never arrives, eventually timing out. + +Example (SNOC): +$ echo stop > /sys/class/remoteproc/remoteproc0/state +[ 71.64] remoteproc remoteproc0: stopped remote processor modem +$ reboot +[ 74.84] ath10k_snoc c800000.wifi: failed to transmit packet, dropping: -108 +[ 74.84] ath10k_snoc c800000.wifi: failed to submit frame: -108 +[...] +[ 82.39] ath10k_snoc c800000.wifi: Timeout in receiving vdev delete response + +To avoid this, skip waiting for the vdev delete response if the firmware is +already marked as unreachable (`ATH10K_FLAG_CRASH_FLUSH`), similar to how +`ath10k_mac_wait_tx_complete()` and `ath10k_vdev_setup_sync()` handle this case. + +Signed-off-by: Loic Poulain +Link: https://patch.msgid.link/20250522131704.612206-1-loic.poulain@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Stable-dep-of: f35a07a4842a ("wifi: ath10k: move recovery check logic into a new work") +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/mac.c | 33 ++++++++++++++++++++------- + 1 file changed, 25 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 74ee3c4f7a6a2..68d049289359b 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -4,6 +4,7 @@ + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include "mac.h" +@@ -1030,6 +1031,26 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) + return ar->last_wmi_vdev_start_status; + } + ++static inline int ath10k_vdev_delete_sync(struct ath10k *ar) ++{ ++ unsigned long time_left; ++ ++ lockdep_assert_held(&ar->conf_mutex); ++ ++ if (!test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) ++ return 0; ++ ++ if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) ++ return -ESHUTDOWN; ++ ++ time_left = wait_for_completion_timeout(&ar->vdev_delete_done, ++ ATH10K_VDEV_DELETE_TIMEOUT_HZ); ++ if (time_left == 0) ++ return -ETIMEDOUT; ++ ++ return 0; ++} ++ + static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) + { + struct cfg80211_chan_def *chandef = NULL; +@@ -5908,7 +5929,6 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, + struct ath10k *ar = hw->priv; + struct ath10k_vif *arvif = (void *)vif->drv_priv; + struct ath10k_peer *peer; +- unsigned long time_left; + int ret; + int i; + +@@ -5948,13 +5968,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw, + ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", + arvif->vdev_id, ret); + +- if (test_bit(WMI_SERVICE_SYNC_DELETE_CMDS, ar->wmi.svc_map)) { +- time_left = wait_for_completion_timeout(&ar->vdev_delete_done, +- ATH10K_VDEV_DELETE_TIMEOUT_HZ); +- if (time_left == 0) { +- ath10k_warn(ar, "Timeout in receiving vdev delete response\n"); +- goto out; +- } ++ ret = ath10k_vdev_delete_sync(ar); ++ if (ret) { ++ ath10k_warn(ar, "Error in receiving vdev delete response: %d\n", ret); ++ goto out; + } + + /* Some firmware revisions don't notify host about self-peer removal +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch b/queue-6.12/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch new file mode 100644 index 0000000000..4689f2a511 --- /dev/null +++ b/queue-6.12/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch @@ -0,0 +1,158 @@ +From 953a07c77af971e69190a78c3c3d7b13be90cabf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 19:07:57 +0800 +Subject: wifi: ath10k: move recovery check logic into a new work +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kang Yang + +[ Upstream commit f35a07a4842a88801d9182b1a76d178bfa616978 ] + +Currently, ath10k has a recovery check logic. It will wait for the +last recovery to finish by wait_for_completion_timeout(); + +But in SDIO scenarios, the recovery function may be invoked from +interrupt context, where long blocking waits are undesirable and can +lead to system instability. + +Additionally, Linux’s ordered workqueue processes one task at a time. +If a previous recovery is still queued or executing, new triggers are +ignored. This prevents accurate tracking of consecutive failures and +delays transition to the WEDGED state. + +To address this, move the recovery check logic into a different +workqueue. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189 + +Fixes: c256a94d1b1b ("wifi: ath10k: shutdown driver when hardware is unreliable") +Signed-off-by: Kang Yang +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251014110757.155-1-kang.yang@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/core.c | 20 +++++++++----------- + drivers/net/wireless/ath/ath10k/core.h | 2 +- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 3 files changed, 11 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index d13acb9e70009..f9b51d98d20bb 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -2486,8 +2485,9 @@ static int ath10k_init_hw_params(struct ath10k *ar) + return 0; + } + +-static bool ath10k_core_needs_recovery(struct ath10k *ar) ++static void ath10k_core_recovery_check_work(struct work_struct *work) + { ++ struct ath10k *ar = container_of(work, struct ath10k, recovery_check_work); + long time_left; + + /* Sometimes the recovery will fail and then the next all recovery fail, +@@ -2497,7 +2497,7 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ath10k_err(ar, "consecutive fail %d times, will shutdown driver!", + atomic_read(&ar->fail_cont_count)); + ar->state = ATH10K_STATE_WEDGED; +- return false; ++ return; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "total recovery count: %d", ++ar->recovery_count); +@@ -2511,27 +2511,24 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ATH10K_RECOVERY_TIMEOUT_HZ); + if (time_left) { + ath10k_warn(ar, "previous recovery succeeded, skip this!\n"); +- return false; ++ return; + } + + /* Record the continuous recovery fail count when recovery failed. */ + atomic_inc(&ar->fail_cont_count); + + /* Avoid having multiple recoveries at the same time. */ +- return false; ++ return; + } + + atomic_inc(&ar->pending_recovery); +- +- return true; ++ queue_work(ar->workqueue, &ar->restart_work); + } + + void ath10k_core_start_recovery(struct ath10k *ar) + { +- if (!ath10k_core_needs_recovery(ar)) +- return; +- +- queue_work(ar->workqueue, &ar->restart_work); ++ /* Use workqueue_aux to avoid blocking recovery tracking */ ++ queue_work(ar->workqueue_aux, &ar->recovery_check_work); + } + EXPORT_SYMBOL(ath10k_core_start_recovery); + +@@ -3727,6 +3724,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, + + INIT_WORK(&ar->register_work, ath10k_core_register_work); + INIT_WORK(&ar->restart_work, ath10k_core_restart); ++ INIT_WORK(&ar->recovery_check_work, ath10k_core_recovery_check_work); + INIT_WORK(&ar->set_coverage_class_work, + ath10k_core_set_coverage_class_work); + +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 85e16c945b5c2..4026cc433b851 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -1208,6 +1207,7 @@ struct ath10k { + + struct work_struct register_work; + struct work_struct restart_work; ++ struct work_struct recovery_check_work; + struct work_struct bundle_tx_work; + struct work_struct tx_complete_work; + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 935923c290e1f..97e0a75237583 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -5426,6 +5425,7 @@ static void ath10k_stop(struct ieee80211_hw *hw, bool suspend) + cancel_work_sync(&ar->set_coverage_class_work); + cancel_delayed_work_sync(&ar->scan.timeout); + cancel_work_sync(&ar->restart_work); ++ cancel_work_sync(&ar->recovery_check_work); + } + + static int ath10k_config_ps(struct ath10k *ar) +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath11k-fix-peer-he-mcs-assignment.patch b/queue-6.12/wifi-ath11k-fix-peer-he-mcs-assignment.patch new file mode 100644 index 0000000000..8b288c087a --- /dev/null +++ b/queue-6.12/wifi-ath11k-fix-peer-he-mcs-assignment.patch @@ -0,0 +1,94 @@ +From 332278f74bbc72e6c1ef016aee44b859d1b13330 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:49:00 +0800 +Subject: wifi: ath11k: fix peer HE MCS assignment + +From: Baochen Qiang + +[ Upstream commit 4a013ca2d490c73c40588d62712ffaa432046a04 ] + +In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to +firmware as receive MCS while peer's receive MCS sent as transmit MCS, +which goes against firmwire's definition. + +While connecting to a misbehaved AP that advertises 0xffff (meaning not +supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff +is assigned to he_mcs->rx_mcs_set field. + + Ext Tag: HE Capabilities + [...] + Supported HE-MCS and NSS Set + [...] + Rx and Tx MCS Maps 160 MHz + [...] + Tx HE-MCS Map 160 MHz: 0xffff + +Swap the assignment to fix this issue. + +As the HE rate control mask is meant to limit our own transmit MCS, it +needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive MCS. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 9521fcb2c11ce..dd5690a4996f3 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2512,10 +2512,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2525,10 +2525,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 6f1fd7d661a89..3b41bc5b125f4 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -2091,8 +2091,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ /* firmware interprets mcs->rx_mcs_set field as peer's ++ * RX capability ++ */ ++ he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath11k-fix-vht-mcs-assignment.patch b/queue-6.12/wifi-ath11k-fix-vht-mcs-assignment.patch new file mode 100644 index 0000000000..d6322b954e --- /dev/null +++ b/queue-6.12/wifi-ath11k-fix-vht-mcs-assignment.patch @@ -0,0 +1,102 @@ +From 57bb251e45d077171762cb7fc29918ec54c80e32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:48:59 +0800 +Subject: wifi: ath11k: fix VHT MCS assignment + +From: Baochen Qiang + +[ Upstream commit 47d0cd6bccb4604192633cc8d29511e85d811fc0 ] + +While associating, firmware needs to know peer's receive capability to +calculate its own VHT transmit MCS, currently host sends this information +to firmware via mcs->rx_mcs_set field, this is wrong as firmware actually +takes it from mcs->tx_mcs_set field. Till now there is no failure seen +due to this, most likely because almost all peers are advertising the +same capability for both transmit and receive. Swap the assignment to +fix it. + +Besides, rate control mask is meant to limit our own transmit MCS, hence +need to go via mcs->tx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive +capability rather than transmit capability. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-1-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 13 ++++++++----- + drivers/net/wireless/ath/ath11k/wmi.h | 2 ++ + 3 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 419c9497800af..9521fcb2c11ce 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2225,9 +2225,9 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); + arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); + arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); ++ arg->rx_mcs_set = ath11k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); + arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); +- arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit( +- __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); ++ arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); + + /* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default. + * VHT mcs rate 10 and 11 is not suppoerted in 11ac standard. +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index bfca9d3639810..6f1fd7d661a89 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -2061,10 +2061,13 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; + + if (param->vht_capable) { +- mcs->rx_max_rate = param->rx_max_rate; +- mcs->rx_mcs_set = param->rx_mcs_set; +- mcs->tx_max_rate = param->tx_max_rate; +- mcs->tx_mcs_set = param->tx_mcs_set; ++ /* firmware interprets mcs->tx_mcs_set field as peer's ++ * RX capability ++ */ ++ mcs->tx_max_rate = param->rx_max_rate; ++ mcs->tx_mcs_set = param->rx_mcs_set; ++ mcs->rx_max_rate = param->tx_max_rate; ++ mcs->rx_mcs_set = param->tx_mcs_set; + } + + /* HE Rates */ +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 9fcffaa2f383c..6e9354297e71d 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -4133,8 +4133,10 @@ struct wmi_rate_set { + struct wmi_vht_rate_set { + u32 tlv_header; + u32 rx_max_rate; ++ /* MCS at which the peer can transmit */ + u32 rx_mcs_set; + u32 tx_max_rate; ++ /* MCS at which the peer can receive */ + u32 tx_mcs_set; + u32 tx_max_mcs_nss; + } __packed; +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath11k-restore-register-window-after-global-res.patch b/queue-6.12/wifi-ath11k-restore-register-window-after-global-res.patch new file mode 100644 index 0000000000..0158d63443 --- /dev/null +++ b/queue-6.12/wifi-ath11k-restore-register-window-after-global-res.patch @@ -0,0 +1,89 @@ +From 67687b4970d118a62595fecbb1f59a276f707ab3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 10:30:20 +0800 +Subject: wifi: ath11k: restore register window after global reset + +From: Baochen Qiang + +[ Upstream commit 596b911644cc19ecba0dbc9c92849fb59390e29a ] + +Hardware target implements an address space larger than that PCI BAR can +map. In order to be able to access the whole target address space, the BAR +space is split into 4 segments, of which the last 3, called windows, can +be dynamically mapped to the desired area. This is achieved by updating +window register with appropriate window value. Currently each time when +accessing a register that beyond ATH11K_PCI_WINDOW_START, host calculates +the window value and caches it after window update, this way next time +when accessing a register falling in the same window, host knows that the +window is already good hence no additional update needed. + +However this mechanism breaks after global reset is triggered in +ath11k_pci_soc_global_reset(), because with global reset hardware resets +window register hence the window is not properly mapped any more. Current +host does nothing about this, as a result a subsequent register access may +not work as expected if it falls in a window same as before. + +Although there is no obvious issue seen now, better to fix it to avoid +future problem. The fix is done by restoring the window register after +global reset. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251014-ath11k-reset-window-cache-v1-1-b85271b111dd@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index c1d576ff77faa..eee83eb6b2c3c 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -175,6 +175,19 @@ static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) + ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + } + ++static void ath11k_pci_restore_window(struct ath11k_base *ab) ++{ ++ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); ++ ++ spin_lock_bh(&ab_pci->window_lock); ++ ++ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | ab_pci->register_window, ++ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ++ spin_unlock_bh(&ab_pci->window_lock); ++} ++ + static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + { + u32 val, delay; +@@ -199,6 +212,11 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); + if (val == 0xffffffff) + ath11k_warn(ab, "link down error during global reset\n"); ++ ++ /* Restore window register as its content is cleared during ++ * hardware global reset, such that it aligns with host cache. ++ */ ++ ath11k_pci_restore_window(ab); + } + + static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab) +-- +2.51.0 + diff --git a/queue-6.12/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch b/queue-6.12/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch new file mode 100644 index 0000000000..fed98f7100 --- /dev/null +++ b/queue-6.12/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch @@ -0,0 +1,39 @@ +From 6400362b53bc2c3fab8b2eaf7aec6f2be3ae7c6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:34:55 +0530 +Subject: wifi: ath12k: fix potential memory leak in + ath12k_wow_arp_ns_offload() + +From: Abdun Nihaal + +[ Upstream commit be5febd51c478bc8e24ad3480435f2754a403b14 ] + +When the call to ath12k_wmi_arp_ns_offload() fails, the temporary memory +allocation for offload is not freed before returning. Fix that by +freeing offload in the error path. + +Fixes: 1666108c74c4 ("wifi: ath12k: support ARP and NS offload") +Signed-off-by: Abdun Nihaal +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251028170457.134608-1-nihaal@cse.iitm.ac.in +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/wow.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c +index 3624180b25b97..d9f310a12be96 100644 +--- a/drivers/net/wireless/ath/ath12k/wow.c ++++ b/drivers/net/wireless/ath/ath12k/wow.c +@@ -755,6 +755,7 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) + if (ret) { + ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n", + arvif->vdev_id, enable, ret); ++ kfree(offload); + return ret; + } + } +-- +2.51.0 + diff --git a/queue-6.12/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-6.12/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..362f58be3e --- /dev/null +++ b/queue-6.12/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From 4494b9a7b70493d2fcc9c76da8654922d7755c3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 3b4ded2ac801c..37232ee220375 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-6.12/wifi-ieee80211-correct-fils-status-codes.patch b/queue-6.12/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..4cbc0e7d34 --- /dev/null +++ b/queue-6.12/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From d027c920bac2f0f1f1e419e731ca9ba1e582f7e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 7ecdde54e1edd..abb069aa5fa54 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3528,8 +3528,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133, +-- +2.51.0 + diff --git a/queue-6.12/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch b/queue-6.12/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch new file mode 100644 index 0000000000..f7d081c1a5 --- /dev/null +++ b/queue-6.12/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch @@ -0,0 +1,196 @@ +From c9452ec12ed5e5db039311b714ca6c542fdd62a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:05:07 +0800 +Subject: wifi: mac80211: fix CMAC functions not handling errors + +From: Chien Wong + +[ Upstream commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb ] + +The called hash functions could fail thus we should check return values. + +Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver") +Signed-off-by: Chien Wong +Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ + net/mac80211/aes_cmac.h | 8 +++--- + net/mac80211/wpa.c | 20 +++++++------ + 3 files changed, 61 insertions(+), 30 deletions(-) + +diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c +index 48c04f89de20a..65989c7dfc680 100644 +--- a/net/mac80211/aes_cmac.c ++++ b/net/mac80211/aes_cmac.c +@@ -22,50 +22,77 @@ + + static const u8 zero[CMAC_TLEN_256]; + +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + u8 out[AES_BLOCK_SIZE]; + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN); ++ err = crypto_shash_update(desc, data, ++ data_len - CMAC_TLEN); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN, out); +- ++ err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); ++ if (err) ++ return err; + memcpy(mic, out, CMAC_TLEN); ++ ++ return 0; + } + +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, +- data_len - 8 - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN_256); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); ++ return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); + } + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h +index 76817446fb838..f74150542142a 100644 +--- a/net/mac80211/aes_cmac.h ++++ b/net/mac80211/aes_cmac.h +@@ -11,10 +11,10 @@ + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len); +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); + void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); + + #endif /* AES_CMAC_H */ +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 293afa3f57c50..f909c48024698 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -872,8 +872,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) + /* + * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) + */ +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -919,8 +920,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) + + /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) + */ +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -959,8 +961,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +@@ -1009,8 +1012,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +-- +2.51.0 + diff --git a/queue-6.12/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-6.12/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..16cd786293 --- /dev/null +++ b/queue-6.12/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 10290883c837de375363d84537a2ae832667a7b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index ded8d4d59289c..1b03310cf639a 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-6.12/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-6.12/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..c7cfa6c18d --- /dev/null +++ b/queue-6.12/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From d20db4b658417a798bb08584dbc0815b848ab1b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index 8a57d6c72335e..876bf79847717 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-6.12/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch b/queue-6.12/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch new file mode 100644 index 0000000000..0670dc1eaa --- /dev/null +++ b/queue-6.12/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch @@ -0,0 +1,87 @@ +From 9fef082d0a2870afefaa9c3a7c20fbd14a04e1d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:22 +0000 +Subject: x86/boot: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit eb2266312507d7b757859e2227aa5c4ba6280ebe ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags. Bits above the + physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The PGD entry is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Acked-by: Dave Hansen +Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index d8c5de40669d3..b20a5790c193d 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include "pgtable.h" + #include "../string.h" +@@ -176,9 +177,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * For 4- to 5-level paging transition, set up current CR3 as + * the first and the only entry in a new top-level page table. + */ +- *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; ++ *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; + } else { +- unsigned long src; ++ u64 *new_cr3; ++ pgd_t *pgdp; + + /* + * For 5- to 4-level paging transition, copy page table pointed +@@ -188,8 +190,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * We cannot just point to the page table from trampoline as it + * may be above 4G. + */ +- src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; +- memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); ++ pgdp = (pgd_t *)native_read_cr3_pa(); ++ new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); ++ memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); + } + + toggle_la57(trampoline_32bit); +-- +2.51.0 + diff --git a/queue-6.12/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-6.12/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..a1d5afb480 --- /dev/null +++ b/queue-6.12/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From a35bbfc7c61f647b6c14526b151b902842900ad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index b2b118a8c09be..5f011e99f0f09 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,8 +183,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -305,6 +305,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-6.17/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch b/queue-6.17/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch new file mode 100644 index 0000000000..47276f0161 --- /dev/null +++ b/queue-6.17/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch @@ -0,0 +1,60 @@ +From 0c24563123b6d1682176730bbb52ae49040583f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 16:30:53 -0600 +Subject: 9p: fix cache/debug options printing in v9fs_show_options + +From: Eric Sandeen + +[ Upstream commit f0445613314f474c1a0ec6fa8a5cd153a618f1b6 ] + +commit 4eb3117888a92 changed the cache= option to accept either string +shortcuts or bitfield values. It also changed /proc/mounts to emit the +option as the hexadecimal numeric value rather than the shortcut string. + +However, by printing "cache=%x" without the leading 0x, shortcuts such +as "cache=loose" will emit "cache=f" and 'f' is not a string that is +parseable by kstrtoint(), so remounting may fail if a remount with +"cache=f" is attempted. + +debug=%x has had the same problem since options have been displayed in +c4fac9100456 ("9p: Implement show_options") + +Fix these by adding the 0x prefix to the hexadecimal value shown in +/proc/mounts. + +Fixes: 4eb3117888a92 ("fs/9p: Rework cache modes and add new options to Documentation") +Signed-off-by: Eric Sandeen +Message-ID: <54b93378-dcf1-4b04-922d-c8b4393da299@redhat.com> +[Dominique: use %#x at Al Viro's suggestion, also handle debug] +Tested-by: Remi Pommarel +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/v9fs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c +index a59c26cc3c7d9..9e2f8f0f82644 100644 +--- a/fs/9p/v9fs.c ++++ b/fs/9p/v9fs.c +@@ -101,7 +101,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; + + if (v9ses->debug) +- seq_printf(m, ",debug=%x", v9ses->debug); ++ seq_printf(m, ",debug=%#x", v9ses->debug); + if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) + seq_printf(m, ",dfltuid=%u", + from_kuid_munged(&init_user_ns, v9ses->dfltuid)); +@@ -117,7 +117,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + if (v9ses->nodev) + seq_puts(m, ",nodevmap"); + if (v9ses->cache) +- seq_printf(m, ",cache=%x", v9ses->cache); ++ seq_printf(m, ",cache=%#x", v9ses->cache); + #ifdef CONFIG_9P_FSCACHE + if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE)) + seq_printf(m, ",cachetag=%s", v9ses->cachetag); +-- +2.51.0 + diff --git a/queue-6.17/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch b/queue-6.17/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch new file mode 100644 index 0000000000..d37ab9b1a2 --- /dev/null +++ b/queue-6.17/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch @@ -0,0 +1,40 @@ +From 1065fc332f92a8ed9e5e37b2565be99a784b0980 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 10:11:15 -0800 +Subject: accel/amdxdna: Clear mailbox interrupt register during channel + creation + +From: Lizhi Hou + +[ Upstream commit 6ff9385c07aa311f01f87307e6256231be7d8675 ] + +The mailbox interrupt register is not always cleared when a mailbox channel +is created. This can leave stale interrupt states from previous operations. + +Fix this by explicitly clearing the interrupt register in the mailbox +channel creation function. + +Fixes: b87f920b9344 ("accel/amdxdna: Support hardware mailbox") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251107181115.1293158-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/amdxdna_mailbox.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.c b/drivers/accel/amdxdna/amdxdna_mailbox.c +index da1ac89bb78f1..6634a4d5717ff 100644 +--- a/drivers/accel/amdxdna/amdxdna_mailbox.c ++++ b/drivers/accel/amdxdna/amdxdna_mailbox.c +@@ -513,6 +513,7 @@ xdna_mailbox_create_channel(struct mailbox *mb, + } + + mb_chann->bad_state = false; ++ mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0); + + MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq); + return mb_chann; +-- +2.51.0 + diff --git a/queue-6.17/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch b/queue-6.17/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch new file mode 100644 index 0000000000..9c94593be1 --- /dev/null +++ b/queue-6.17/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch @@ -0,0 +1,54 @@ +From a5da125b47966dcdfc512c62b475ea27d2925af3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 10:10:50 -0800 +Subject: accel/amdxdna: Fix deadlock between context destroy and job timeout + +From: Lizhi Hou + +[ Upstream commit ca2583412306ceda9304a7c4302fd9efbf43e963 ] + +Hardware context destroy function holds dev_lock while waiting for all jobs +to complete. The timeout job also needs to acquire dev_lock, this leads to +a deadlock. + +Fix the issue by temporarily releasing dev_lock before waiting for all +jobs to finish, and reacquiring it afterward. + +Fixes: 4fd6ca90fc7f ("accel/amdxdna: Refactor hardware context destroy routine") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251107181050.1293125-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index b02f84121f3a5..8e6a608974791 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -675,17 +675,19 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx) + ndev->hwctx_num--; + + XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq); +- drm_sched_entity_destroy(&hwctx->priv->entity); +- + aie2_hwctx_wait_for_idle(hwctx); + + /* Request fw to destroy hwctx and cancel the rest pending requests */ + aie2_release_resource(hwctx); + ++ mutex_unlock(&xdna->dev_lock); ++ drm_sched_entity_destroy(&hwctx->priv->entity); ++ + /* Wait for all submitted jobs to be completed or canceled */ + wait_event(hwctx->priv->job_free_wq, + atomic64_read(&hwctx->job_submit_cnt) == + atomic64_read(&hwctx->job_free_cnt)); ++ mutex_lock(&xdna->dev_lock); + + drm_sched_fini(&hwctx->priv->sched); + aie2_ctx_syncobj_destroy(hwctx); +-- +2.51.0 + diff --git a/queue-6.17/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch b/queue-6.17/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch new file mode 100644 index 0000000000..ba62f08ad7 --- /dev/null +++ b/queue-6.17/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch @@ -0,0 +1,51 @@ +From 161d66c1529bb7bfa3408b9aedb55311dbe3ec4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 11:41:40 -0800 +Subject: accel/amdxdna: Fix dma_fence leak when job is canceled + +From: Lizhi Hou + +[ Upstream commit dea9f84776b96a703f504631ebe9fea07bd2c181 ] + +Currently, dma_fence_put(job->fence) is called in job notification +callback. However, if a job is canceled, the notification callback is never +invoked, leading to a memory leak. Move dma_fence_put(job->fence) +to the job cleanup function to ensure the fence is always released. + +Fixes: aac243092b70 ("accel/amdxdna: Add command execution") +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251105194140.1004314-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 1 - + drivers/accel/amdxdna/amdxdna_ctx.c | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index 3a9239da588c5..b02f84121f3a5 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -183,7 +183,6 @@ aie2_sched_notify(struct amdxdna_sched_job *job) + + up(&job->hwctx->priv->job_sem); + job->job_done = true; +- dma_fence_put(fence); + mmput_async(job->mm); + aie2_job_put(job); + } +diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c +index b47a7f8e90170..7242af5346f98 100644 +--- a/drivers/accel/amdxdna/amdxdna_ctx.c ++++ b/drivers/accel/amdxdna/amdxdna_ctx.c +@@ -375,6 +375,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job) + trace_amdxdna_debug_point(job->hwctx->name, job->seq, "job release"); + amdxdna_arg_bos_put(job); + amdxdna_gem_put_obj(job->cmd_bo); ++ dma_fence_put(job->fence); + } + + int amdxdna_cmd_submit(struct amdxdna_client *client, +-- +2.51.0 + diff --git a/queue-6.17/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch b/queue-6.17/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch new file mode 100644 index 0000000000..65d4b69bbb --- /dev/null +++ b/queue-6.17/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch @@ -0,0 +1,80 @@ +From f1b9319a08fc4164ecf76bd615b19972d07151d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 12:34:23 -0700 +Subject: accel/amdxdna: Fix incorrect command state for timed out job + +From: Lizhi Hou + +[ Upstream commit 6fb7f298883246e21f60f971065adcb789ae6eba ] + +When a command times out, mark it as ERT_CMD_STATE_TIMEOUT. Any other +commands that are canceled due to this timeout should be marked as +ERT_CMD_STATE_ABORT. + +Fixes: aac243092b70 ("accel/amdxdna: Add command execution") +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251029193423.2430463-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 15 +++++++++++++-- + drivers/accel/amdxdna/amdxdna_ctx.h | 1 + + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index 6f77d1794e483..3a9239da588c5 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -198,10 +198,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) + + cmd_abo = job->cmd_bo; + +- if (unlikely(!data)) ++ if (unlikely(job->job_timeout)) { ++ amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); ++ ret = -EINVAL; + goto out; ++ } + +- if (unlikely(size != sizeof(u32))) { ++ if (unlikely(!data) || unlikely(size != sizeof(u32))) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + ret = -EINVAL; + goto out; +@@ -254,6 +257,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) + int ret = 0; + + cmd_abo = job->cmd_bo; ++ ++ if (unlikely(job->job_timeout)) { ++ amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); ++ ret = -EINVAL; ++ goto out; ++ } ++ + if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + ret = -EINVAL; +@@ -356,6 +366,7 @@ aie2_sched_job_timedout(struct drm_sched_job *sched_job) + + xdna = hwctx->client->xdna; + trace_xdna_job(sched_job, hwctx->name, "job timedout", job->seq); ++ job->job_timeout = true; + mutex_lock(&xdna->dev_lock); + aie2_hwctx_stop(xdna, hwctx, sched_job); + +diff --git a/drivers/accel/amdxdna/amdxdna_ctx.h b/drivers/accel/amdxdna/amdxdna_ctx.h +index c652229547a3c..e454b19d6ba73 100644 +--- a/drivers/accel/amdxdna/amdxdna_ctx.h ++++ b/drivers/accel/amdxdna/amdxdna_ctx.h +@@ -105,6 +105,7 @@ struct amdxdna_sched_job { + /* user can wait on this fence */ + struct dma_fence *out_fence; + bool job_done; ++ bool job_timeout; + u64 seq; + struct amdxdna_gem_obj *cmd_bo; + size_t bo_cnt; +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch b/queue-6.17/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch new file mode 100644 index 0000000000..cad2f95bb0 --- /dev/null +++ b/queue-6.17/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch @@ -0,0 +1,51 @@ +From d43824e3812c8b7ed52f800744d89b66ff59406e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 10:48:09 +0200 +Subject: accel/ivpu: Ensure rpm_runtime_put in case of engine reset/resume + fail + +From: Karol Wachowski + +[ Upstream commit 9f6c63285737b141ca25a619add80a96111b8b96 ] + +Previously, aborting work could return early after engine reset or resume +failure, skipping the necessary runtime_put cleanup leaving the device +with incorrect reference count breaking runtime power management state. + +Replace early returns with goto statements to ensure runtime_put is always +executed. + +Fixes: a47e36dc5d90 ("accel/ivpu: Trigger device recovery on engine reset/resume failure") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250916084809.850073-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_job.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index 060f1fc031d34..dbefa43c74e28 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -1012,7 +1012,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) + + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (ivpu_jsm_reset_engine(vdev, 0)) +- return; ++ goto runtime_put; + + mutex_lock(&vdev->context_list_lock); + xa_for_each(&vdev->context_xa, ctx_id, file_priv) { +@@ -1036,7 +1036,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) + goto runtime_put; + + if (ivpu_jsm_hws_resume_engine(vdev, 0)) +- return; ++ goto runtime_put; + /* + * In hardware scheduling mode NPU already has stopped processing jobs + * and won't send us any further notifications, thus we have to free job related resources +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-fix-dct-active-percent-format.patch b/queue-6.17/accel-ivpu-fix-dct-active-percent-format.patch new file mode 100644 index 0000000000..c38caab263 --- /dev/null +++ b/queue-6.17/accel-ivpu-fix-dct-active-percent-format.patch @@ -0,0 +1,71 @@ +From 79ae5e8c7d6e5ae9c43e43f750ebc756f4ca6297 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:43:22 +0200 +Subject: accel/ivpu: Fix DCT active percent format + +From: Karol Wachowski + +[ Upstream commit aa1c2b073ad23847dd2e7bdc7d30009f34ed7f59 ] + +The pcode MAILBOX STATUS register PARAM2 field expects DCT active +percent in U1.7 value format. Convert percentage value to this +format before writing to the register. + +Fixes: a19bffb10c46 ("accel/ivpu: Implement DCT handling") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20251001104322.1249896-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + drivers/accel/ivpu/ivpu_pm.c | 9 +++++++-- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c +index b236c7234daab..05f4133c3511a 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.c ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c +@@ -753,7 +753,7 @@ int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable) + } + } + +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent) ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent) + { + u32 val = 0; + u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE; +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 032c384ac3d4d..c4c10e22f30f3 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -36,7 +36,7 @@ u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); + bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); + bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); + int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent); + u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); +diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c +index 475ddc94f1cfe..457ccf09df545 100644 +--- a/drivers/accel/ivpu/ivpu_pm.c ++++ b/drivers/accel/ivpu/ivpu_pm.c +@@ -502,6 +502,11 @@ void ivpu_pm_irq_dct_work_fn(struct work_struct *work) + else + ret = ivpu_pm_dct_disable(vdev); + +- if (!ret) +- ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent); ++ if (!ret) { ++ /* Convert percent to U1.7 format */ ++ u8 val = DIV_ROUND_CLOSEST(vdev->pm->dct_active_percent * 128, 100); ++ ++ ivpu_hw_btrs_dct_set_status(vdev, enable, val); ++ } ++ + } +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch b/queue-6.17/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch new file mode 100644 index 0000000000..44d325fbf9 --- /dev/null +++ b/queue-6.17/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch @@ -0,0 +1,91 @@ +From e0140c26a4e368fbf6a06a1ab403550b0e1c9ea6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 16:51:14 +0200 +Subject: accel/ivpu: Fix page fault in ivpu_bo_unbind_all_bos_from_context() + +From: Jacek Lawrynowicz + +[ Upstream commit 8b694b405a84696f1d964f6da7cf9721e68c4714 ] + +Don't add BO to the vdev->bo_list in ivpu_gem_create_object(). +When failure happens inside drm_gem_shmem_create(), the BO is not +fully created and ivpu_gem_bo_free() callback will not be called +causing a deleted BO to be left on the list. + +Fixes: 8d88e4cdce4f ("accel/ivpu: Use GEM shmem helper for all buffers") +Signed-off-by: Jacek Lawrynowicz +Signed-off-by: Maciej Falkowski +Reviewed-by: Karol Wachowski +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250925145114.1446283-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index dc6d0d15cda9c..171e809575ad6 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -193,7 +193,6 @@ void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_m + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size) + { +- struct ivpu_device *vdev = to_ivpu_device(dev); + struct ivpu_bo *bo; + + if (size == 0 || !PAGE_ALIGNED(size)) +@@ -208,20 +207,17 @@ struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t siz + + INIT_LIST_HEAD(&bo->bo_list_node); + +- mutex_lock(&vdev->bo_list_lock); +- list_add_tail(&bo->bo_list_node, &vdev->bo_list); +- mutex_unlock(&vdev->bo_list_lock); +- +- ivpu_dbg(vdev, BO, " alloc: bo %8p size %9zu\n", bo, size); + return &bo->base.base; + } + + struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf) + { ++ struct ivpu_device *vdev = to_ivpu_device(dev); + struct device *attach_dev = dev->dev; + struct dma_buf_attachment *attach; + struct drm_gem_object *obj; ++ struct ivpu_bo *bo; + int ret; + + attach = dma_buf_attach(dma_buf, attach_dev); +@@ -239,6 +235,14 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + obj->import_attach = attach; + obj->resv = dma_buf->resv; + ++ bo = to_ivpu_bo(obj); ++ ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, "import: bo %8p size %9zu\n", bo, ivpu_bo_size(bo)); ++ + return obj; + + fail_detach: +@@ -269,6 +273,12 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla + bo->base.map_wc = flags & DRM_IVPU_BO_WC; + bo->flags = flags; + ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, " alloc: bo %8p size %9llu\n", bo, size); ++ + return bo; + } + +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch b/queue-6.17/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch new file mode 100644 index 0000000000..697ece5250 --- /dev/null +++ b/queue-6.17/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch @@ -0,0 +1,45 @@ +From 0f472f7d330b05d0910fd70faad632cac3313792 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 09:17:25 +0200 +Subject: accel/ivpu: Fix race condition when mapping dmabuf + +From: Wludzik, Jozef + +[ Upstream commit 63c7870fab67b2ab2bfe75e8b46f3c37b88c47a8 ] + +Fix a race that can occur when multiple jobs submit the same dmabuf. +This could cause the sg_table to be mapped twice, leading to undefined +behavior. + +Fixes: e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +Signed-off-by: Wludzik, Jozef +Reviewed-by: Jeff Hugo +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20251014071725.3047287-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 171e809575ad6..1fca969df19dc 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -45,12 +45,13 @@ static inline void ivpu_bo_unlock(struct ivpu_bo *bo) + + static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct ivpu_bo *bo) + { +- struct sg_table *sgt = bo->base.sgt; ++ struct sg_table *sgt; + + drm_WARN_ON(&vdev->drm, !bo->base.base.import_attach); + + ivpu_bo_lock(bo); + ++ sgt = bo->base.sgt; + if (!sgt) { + sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-fix-race-condition-when-unbinding-bos.patch b/queue-6.17/accel-ivpu-fix-race-condition-when-unbinding-bos.patch new file mode 100644 index 0000000000..d5ec591122 --- /dev/null +++ b/queue-6.17/accel-ivpu-fix-race-condition-when-unbinding-bos.patch @@ -0,0 +1,53 @@ +From 88b6cd1d8e926db8018a97b5ef7f0d2e06dcb1d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 08:14:51 +0100 +Subject: accel/ivpu: Fix race condition when unbinding BOs + +From: Tomasz Rusinowicz + +[ Upstream commit 00812636df370bedf4e44a0c81b86ea96bca8628 ] + +Fix 'Memory manager not clean during takedown' warning that occurs +when ivpu_gem_bo_free() removes the BO from the BOs list before it +gets unmapped. Then file_priv_unbind() triggers a warning in +drm_mm_takedown() during context teardown. + +Protect the unmapping sequence with bo_list_lock to ensure the BO is +always fully unmapped when removed from the list. This ensures the BO +is either fully unmapped at context teardown time or present on the +list and unmapped by file_priv_unbind(). + +Fixes: 48aea7f2a2ef ("accel/ivpu: Fix locking in ivpu_bo_remove_all_bos_from_context()") +Signed-off-by: Tomasz Rusinowicz +Reviewed-by: Jeff Hugo +Signed-off-by: Karol Wachowski +Link: https://patch.msgid.link/20251029071451.184243-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index a38e41f9c7123..fda0a18e6d639 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -314,7 +314,6 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + + mutex_lock(&vdev->bo_list_lock); + list_del(&bo->bo_list_node); +- mutex_unlock(&vdev->bo_list_lock); + + drm_WARN_ON(&vdev->drm, !drm_gem_is_imported(&bo->base.base) && + !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ)); +@@ -325,6 +324,8 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + ivpu_bo_unbind_locked(bo); + ivpu_bo_unlock(bo); + ++ mutex_unlock(&vdev->bo_list_lock); ++ + drm_WARN_ON(&vdev->drm, bo->mmu_mapped); + drm_WARN_ON(&vdev->drm, bo->ctx); + +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-make-function-parameter-names-consistent.patch b/queue-6.17/accel-ivpu-make-function-parameter-names-consistent.patch new file mode 100644 index 0000000000..f37152f935 --- /dev/null +++ b/queue-6.17/accel-ivpu-make-function-parameter-names-consistent.patch @@ -0,0 +1,51 @@ +From 5188b2be313c05f36c004ec6a781a87f9eb1e6ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Aug 2025 13:10:14 +0200 +Subject: accel/ivpu: Make function parameter names consistent + +From: Jacek Lawrynowicz + +[ Upstream commit cf87f93847dea607e8a35983cb006ef8493f8065 ] + +Make ivpu_hw_btrs_dct_set_status() and ivpu_fw_boot_params_setup() +declaration and definition parameter names consistent. + +Reviewed-by: Lizhi Hou +Signed-off-by: Jacek Lawrynowicz +Link: https://lore.kernel.org/r/20250808111014.328607-1-jacek.lawrynowicz@linux.intel.com +Stable-dep-of: aa1c2b073ad2 ("accel/ivpu: Fix DCT active percent format") +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_fw.h | 2 +- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_fw.h b/drivers/accel/ivpu/ivpu_fw.h +index 9a3935be1c057..7081913fb0dde 100644 +--- a/drivers/accel/ivpu/ivpu_fw.h ++++ b/drivers/accel/ivpu/ivpu_fw.h +@@ -45,7 +45,7 @@ struct ivpu_fw_info { + int ivpu_fw_init(struct ivpu_device *vdev); + void ivpu_fw_fini(struct ivpu_device *vdev); + void ivpu_fw_load(struct ivpu_device *vdev); +-void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *bp); ++void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params *boot_params); + + static inline bool ivpu_fw_is_cold_boot(struct ivpu_device *vdev) + { +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index d2d82651976d1..032c384ac3d4d 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -36,7 +36,7 @@ u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); + bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); + bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); + int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 dct_percent); ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); + u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch b/queue-6.17/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch new file mode 100644 index 0000000000..01a896cdf9 --- /dev/null +++ b/queue-6.17/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch @@ -0,0 +1,44 @@ +From fe9224592fe1edd0f9a31d6396ba8dea95470255 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 16:09:32 +0100 +Subject: accel/ivpu: Remove skip of dma unmap for imported buffers + +From: Maciej Falkowski + +[ Upstream commit c063c1bbee67391f12956d2ffdd5da00eb87ff79 ] + +Rework of imported buffers introduced in the commit +e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +switched the logic of imported buffers by dma mapping/unmapping +them just as the regular buffers. + +The commit didn't include removal of skipping dma unmap of imported +buffers which results in them being mapped without unmapping. + +Fixes: e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +Reviewed-by: Jeff Hugo +Reviewed-by: Karol Wachowski +Signed-off-by: Maciej Falkowski +Link: https://patch.msgid.link/20251027150933.2384538-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 1fca969df19dc..a38e41f9c7123 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -157,9 +157,6 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + bo->ctx = NULL; + } + +- if (drm_gem_is_imported(&bo->base.base)) +- return; +- + if (bo->base.sgt) { + if (bo->base.base.import_attach) { + dma_buf_unmap_attachment(bo->base.base.import_attach, +-- +2.51.0 + diff --git a/queue-6.17/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch b/queue-6.17/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch new file mode 100644 index 0000000000..985feeb8ee --- /dev/null +++ b/queue-6.17/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch @@ -0,0 +1,301 @@ +From 5edfc9a1021f6392ae8607030b64e4ead8a237aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 16:50:59 +0200 +Subject: accel/ivpu: Rework bind/unbind of imported buffers + +From: Jacek Lawrynowicz + +[ Upstream commit e0c0891cd63bf8338c25c423e28a5a93aed3d74c ] + +Ensure that imported buffers are properly mapped and unmapped in +the same way as regular buffers to properly handle buffers during +device's bind and unbind operations to prevent resource leaks and +inconsistent buffer states. + +Imported buffers are now dma_mapped before submission and +dma_unmapped in ivpu_bo_unbind(), guaranteeing they are unmapped +when the device is unbound. + +Add also imported buffers to vdev->bo_list for consistent unmapping +on device unbind. The bo->ctx_id is set in open() so imported +buffers have a valid context ID. + +Debug logs have been updated to match the new code structure. +The function ivpu_bo_pin() has been renamed to ivpu_bo_bind() +to better reflect its purpose, and unbind tests have been refactored +for improved coverage and clarity. + +Signed-off-by: Jacek Lawrynowicz +Signed-off-by: Maciej Falkowski +Reviewed-by: Karol Wachowski +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250925145059.1446243-1-maciej.falkowski@linux.intel.com +Stable-dep-of: 8b694b405a84 ("accel/ivpu: Fix page fault in ivpu_bo_unbind_all_bos_from_context()") +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 90 ++++++++++++++++++++++------------- + drivers/accel/ivpu/ivpu_gem.h | 2 +- + drivers/accel/ivpu/ivpu_job.c | 2 +- + 3 files changed, 60 insertions(+), 34 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 59cfcf3eaded9..dc6d0d15cda9c 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -27,8 +27,8 @@ static const struct drm_gem_object_funcs ivpu_gem_funcs; + static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action) + { + ivpu_dbg(vdev, BO, +- "%6s: bo %8p vpu_addr %9llx size %8zu ctx %d has_pages %d dma_mapped %d mmu_mapped %d wc %d imported %d\n", +- action, bo, bo->vpu_addr, ivpu_bo_size(bo), bo->ctx_id, ++ "%6s: bo %8p size %9zu ctx %d vpu_addr %9llx pages %d sgt %d mmu_mapped %d wc %d imported %d\n", ++ action, bo, ivpu_bo_size(bo), bo->ctx_id, bo->vpu_addr, + (bool)bo->base.pages, (bool)bo->base.sgt, bo->mmu_mapped, bo->base.map_wc, + (bool)drm_gem_is_imported(&bo->base.base)); + } +@@ -43,22 +43,46 @@ static inline void ivpu_bo_unlock(struct ivpu_bo *bo) + dma_resv_unlock(bo->base.base.resv); + } + ++static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct ivpu_bo *bo) ++{ ++ struct sg_table *sgt = bo->base.sgt; ++ ++ drm_WARN_ON(&vdev->drm, !bo->base.base.import_attach); ++ ++ ivpu_bo_lock(bo); ++ ++ if (!sgt) { ++ sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL); ++ if (IS_ERR(sgt)) ++ ivpu_err(vdev, "Failed to map BO in IOMMU: %ld\n", PTR_ERR(sgt)); ++ else ++ bo->base.sgt = sgt; ++ } ++ ++ ivpu_bo_unlock(bo); ++ ++ return sgt; ++} ++ + /* +- * ivpu_bo_pin() - pin the backing physical pages and map them to VPU. ++ * ivpu_bo_bind() - pin the backing physical pages and map them to VPU. + * + * This function pins physical memory pages, then maps the physical pages + * to IOMMU address space and finally updates the VPU MMU page tables + * to allow the VPU to translate VPU address to IOMMU address. + */ +-int __must_check ivpu_bo_pin(struct ivpu_bo *bo) ++int __must_check ivpu_bo_bind(struct ivpu_bo *bo) + { + struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); + struct sg_table *sgt; + int ret = 0; + +- ivpu_dbg_bo(vdev, bo, "pin"); ++ ivpu_dbg_bo(vdev, bo, "bind"); + +- sgt = drm_gem_shmem_get_pages_sgt(&bo->base); ++ if (bo->base.base.import_attach) ++ sgt = ivpu_bo_map_attachment(vdev, bo); ++ else ++ sgt = drm_gem_shmem_get_pages_sgt(&bo->base); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + ivpu_err(vdev, "Failed to map BO in IOMMU: %d\n", ret); +@@ -99,7 +123,9 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, + ret = ivpu_mmu_context_insert_node(ctx, range, ivpu_bo_size(bo), &bo->mm_node); + if (!ret) { + bo->ctx = ctx; ++ bo->ctx_id = ctx->id; + bo->vpu_addr = bo->mm_node.start; ++ ivpu_dbg_bo(vdev, bo, "vaddr"); + } else { + ivpu_err(vdev, "Failed to add BO to context %u: %d\n", ctx->id, ret); + } +@@ -115,7 +141,7 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + { + struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); + +- lockdep_assert(dma_resv_held(bo->base.base.resv) || !kref_read(&bo->base.base.refcount)); ++ dma_resv_assert_held(bo->base.base.resv); + + if (bo->mmu_mapped) { + drm_WARN_ON(&vdev->drm, !bo->ctx); +@@ -134,9 +160,14 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + return; + + if (bo->base.sgt) { +- dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); +- sg_free_table(bo->base.sgt); +- kfree(bo->base.sgt); ++ if (bo->base.base.import_attach) { ++ dma_buf_unmap_attachment(bo->base.base.import_attach, ++ bo->base.sgt, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); ++ sg_free_table(bo->base.sgt); ++ kfree(bo->base.sgt); ++ } + bo->base.sgt = NULL; + } + } +@@ -162,6 +193,7 @@ void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_m + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size) + { ++ struct ivpu_device *vdev = to_ivpu_device(dev); + struct ivpu_bo *bo; + + if (size == 0 || !PAGE_ALIGNED(size)) +@@ -176,6 +208,11 @@ struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t siz + + INIT_LIST_HEAD(&bo->bo_list_node); + ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, " alloc: bo %8p size %9zu\n", bo, size); + return &bo->base.base; + } + +@@ -184,7 +221,6 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + { + struct device *attach_dev = dev->dev; + struct dma_buf_attachment *attach; +- struct sg_table *sgt; + struct drm_gem_object *obj; + int ret; + +@@ -194,16 +230,10 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + + get_dma_buf(dma_buf); + +- sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL); +- if (IS_ERR(sgt)) { +- ret = PTR_ERR(sgt); +- goto fail_detach; +- } +- +- obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt); ++ obj = drm_gem_shmem_prime_import_sg_table(dev, attach, NULL); + if (IS_ERR(obj)) { + ret = PTR_ERR(obj); +- goto fail_unmap; ++ goto fail_detach; + } + + obj->import_attach = attach; +@@ -211,8 +241,6 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + + return obj; + +-fail_unmap: +- dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL); + fail_detach: + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); +@@ -220,7 +248,7 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + return ERR_PTR(ret); + } + +-static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags, u32 ctx_id) ++static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags) + { + struct drm_gem_shmem_object *shmem; + struct ivpu_bo *bo; +@@ -238,16 +266,9 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla + return ERR_CAST(shmem); + + bo = to_ivpu_bo(&shmem->base); +- bo->ctx_id = ctx_id; + bo->base.map_wc = flags & DRM_IVPU_BO_WC; + bo->flags = flags; + +- mutex_lock(&vdev->bo_list_lock); +- list_add_tail(&bo->bo_list_node, &vdev->bo_list); +- mutex_unlock(&vdev->bo_list_lock); +- +- ivpu_dbg_bo(vdev, bo, "alloc"); +- + return bo; + } + +@@ -281,6 +302,8 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + + ivpu_dbg_bo(vdev, bo, "free"); + ++ drm_WARN_ON(&vdev->drm, list_empty(&bo->bo_list_node)); ++ + mutex_lock(&vdev->bo_list_lock); + list_del(&bo->bo_list_node); + mutex_unlock(&vdev->bo_list_lock); +@@ -290,7 +313,10 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + drm_WARN_ON(&vdev->drm, ivpu_bo_size(bo) == 0); + drm_WARN_ON(&vdev->drm, bo->base.vaddr); + ++ ivpu_bo_lock(bo); + ivpu_bo_unbind_locked(bo); ++ ivpu_bo_unlock(bo); ++ + drm_WARN_ON(&vdev->drm, bo->mmu_mapped); + drm_WARN_ON(&vdev->drm, bo->ctx); + +@@ -326,7 +352,7 @@ int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fi + if (size == 0) + return -EINVAL; + +- bo = ivpu_bo_alloc(vdev, size, args->flags, file_priv->ctx.id); ++ bo = ivpu_bo_alloc(vdev, size, args->flags); + if (IS_ERR(bo)) { + ivpu_err(vdev, "Failed to allocate BO: %pe (ctx %u size %llu flags 0x%x)", + bo, file_priv->ctx.id, args->size, args->flags); +@@ -360,7 +386,7 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, + drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(range->end)); + drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(size)); + +- bo = ivpu_bo_alloc(vdev, size, flags, IVPU_GLOBAL_CONTEXT_MMU_SSID); ++ bo = ivpu_bo_alloc(vdev, size, flags); + if (IS_ERR(bo)) { + ivpu_err(vdev, "Failed to allocate BO: %pe (vpu_addr 0x%llx size %llu flags 0x%x)", + bo, range->start, size, flags); +@@ -371,7 +397,7 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, + if (ret) + goto err_put; + +- ret = ivpu_bo_pin(bo); ++ ret = ivpu_bo_bind(bo); + if (ret) + goto err_put; + +diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h +index aa8ff14f7aae1..ade0d127453ff 100644 +--- a/drivers/accel/ivpu/ivpu_gem.h ++++ b/drivers/accel/ivpu/ivpu_gem.h +@@ -24,7 +24,7 @@ struct ivpu_bo { + bool mmu_mapped; + }; + +-int ivpu_bo_pin(struct ivpu_bo *bo); ++int ivpu_bo_bind(struct ivpu_bo *bo); + void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size); +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index dbefa43c74e28..1e4caf5726474 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -732,7 +732,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 + + job->bos[i] = to_ivpu_bo(obj); + +- ret = ivpu_bo_pin(job->bos[i]); ++ ret = ivpu_bo_bind(job->bos[i]); + if (ret) + return ret; + } +-- +2.51.0 + diff --git a/queue-6.17/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-6.17/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..3e68c7e101 --- /dev/null +++ b/queue-6.17/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 3c4ccda4a0d702ec0d3472527643f7413f537118 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 9b6b71a2ffb54..a4498357bd165 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-6.17/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-6.17/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..243a01ab9c --- /dev/null +++ b/queue-6.17/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 1db58ebdad2c5570635f7c4e90c760fed097c26a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index d74678f0ba4af..57bf9c973c4f7 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1693,6 +1693,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch b/queue-6.17/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch new file mode 100644 index 0000000000..e4079c5b4d --- /dev/null +++ b/queue-6.17/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch @@ -0,0 +1,41 @@ +From 0cb5ee4c5a1e81af67fccca450873dc65d261bd2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:38:51 +0200 +Subject: ARM: dts: am335x-netcom-plus-2xx: add missing GPIO labels + +From: Yegor Yefremov + +[ Upstream commit d0c4b1723c419a18cb434903c7754954ecb51d35 ] + +Fixes: 8e9d75fd2ec2 ("ARM: dts: am335x-netcom: add GPIO names for NetCom Plus 2-port devices") + +Signed-off-by: Yegor Yefremov +Link: https://lore.kernel.org/r/20251007103851.3765678-1-yegorslists@googlemail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +index f66d57bb685ee..f0519ab301416 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +@@ -222,10 +222,10 @@ &gpio3 { + "ModeA1", + "ModeA2", + "ModeA3", +- "NC", +- "NC", +- "NC", +- "NC", ++ "ModeB0", ++ "ModeB1", ++ "ModeB2", ++ "ModeB3", + "NC", + "NC", + "NC", +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch b/queue-6.17/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch new file mode 100644 index 0000000000..da521c5851 --- /dev/null +++ b/queue-6.17/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch @@ -0,0 +1,43 @@ +From 21563db01fa035642fbe7d99b4c3034f082e579e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:15 +0200 +Subject: ARM: dts: omap3: beagle-xm: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit f7f3bc18300a230e0f1bfb17fc8889435c1e47f5 ] + +The "ti,twl4030-power-beagleboard-xm" compatible string is obsolete and +is not supported by any in-kernel driver. Currently, the kernel falls +back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a +driver to this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: 9188883fd66e9 ("ARM: dts: Enable twl4030 off-idle configuration for selected omaps") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-3-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +index 08ee0f8ea68fd..71b39a923d37c 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +@@ -291,7 +291,7 @@ codec { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch b/queue-6.17/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch new file mode 100644 index 0000000000..01c413cc35 --- /dev/null +++ b/queue-6.17/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch @@ -0,0 +1,43 @@ +From ff887ccd7e0e8eab166f597ee1c58c1dba454d64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:16 +0200 +Subject: ARM: dts: omap3: n900: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit 3862123e9b56663c7a3e4a308e6e65bffe44f646 ] + +The "ti,twl4030-power-n900" compatible string is obsolete and is not +supported by any in-kernel driver. Currently, the kernel falls back to +the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to +this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: daebabd578647 ("mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-4-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-n900.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +index c50ca572d1b9b..7db73d9bed9e4 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +@@ -508,7 +508,7 @@ twl_audio: audio { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-renesas-gose-remove-superfluous-port-propert.patch b/queue-6.17/arm-dts-renesas-gose-remove-superfluous-port-propert.patch new file mode 100644 index 0000000000..5caa14898c --- /dev/null +++ b/queue-6.17/arm-dts-renesas-gose-remove-superfluous-port-propert.patch @@ -0,0 +1,39 @@ +From 3656ec12a016f7d2950f6d9a5d4b12f389624aa4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 11:36:02 +0200 +Subject: ARM: dts: renesas: gose: Remove superfluous port property + +From: Wolfram Sang + +[ Upstream commit 00df14f34615630f92f97c9d6790bd9d25c4242d ] + +'bus-width' is defined for the corresponding vin input port already. +No need to declare it in the output port again. Fixes: + + arch/arm/boot/dts/renesas/r8a7793-gose.dtb: composite-in@20 (adi,adv7180cp): ports:port@3:endpoint: Unevaluated properties are not allowed ('bus-width' was unexpected) + from schema $id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml# + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250929093616.17679-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r8a7793-gose.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +index 45b267ec26794..5c6928c941aca 100644 +--- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts ++++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +@@ -373,7 +373,6 @@ adv7180_in: endpoint { + port@3 { + reg = <3>; + adv7180_out: endpoint { +- bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch b/queue-6.17/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch new file mode 100644 index 0000000000..91acf075d7 --- /dev/null +++ b/queue-6.17/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch @@ -0,0 +1,41 @@ +From 24c0b68af4c74fd0fe1cf61a120c747f3230326c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:46:25 +0200 +Subject: ARM: dts: renesas: r9a06g032-rzn1d400-db: Drop invalid #cells + properties + +From: Wolfram Sang + +[ Upstream commit ca7fffb6e92a7c93604ea2bae0e1c89b20750937 ] + +The 'ethernet-ports' node in the SoC DTSI handles them already. Fixes: + + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dtb: switch@44050000 (renesas,r9a06g032-a5psw): Unevaluated properties are not allowed ('#address-cells', '#size-cells' were unexpected) + from schema $id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# + +Fixes: 5b6d7c3c5861ad4a ("ARM: dts: r9a06g032-rzn1d400-db: Add switch description") +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251007104624.19786-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +index 3258b2e274346..4a72aa7663f25 100644 +--- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts ++++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +@@ -308,8 +308,6 @@ &rtc0 { + + &switch { + status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch b/queue-6.17/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..fcd6676e49 --- /dev/null +++ b/queue-6.17/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 1d6d17038f5d4d66e6e081347d5198377a86d7f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:16 +0100 +Subject: ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-3-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +index df229fb8a16be..8a635bee59fa9 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +@@ -853,6 +853,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&vtf_reg>; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch b/queue-6.17/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..fabf05b2d6 --- /dev/null +++ b/queue-6.17/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 01f65735b050f9763f43adc154b42da5600f8539 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:17 +0100 +Subject: ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97cc9c346b2c9cde075b9420fc172137d2427711 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: a19f6efc01df ("ARM: dts: exynos: Enable WLAN support for the Trats board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-4-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +index 95e0e01b6ff6b..6bd902cb8f4ad 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +@@ -518,6 +518,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&tflash_reg>; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch b/queue-6.17/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..eb9801a57c --- /dev/null +++ b/queue-6.17/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 660cf59a6dd41dfaf5f83d848605c515f1a1b482 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:18 +0100 +Subject: ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f77cbb9a3e5d ("ARM: dts: exynos: Add bcm4334 device node to Trats2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-5-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +index 05ddddb565ee3..48245b1665a69 100644 +--- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +@@ -1440,6 +1440,7 @@ &sdhci_3 { + #address-cells = <1>; + #size-cells = <0>; + non-removable; ++ cap-power-off-card; + bus-width = <4>; + + mmc-pwrseq = <&wlan_pwrseq>; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch b/queue-6.17/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch new file mode 100644 index 0000000000..b7ce54a00f --- /dev/null +++ b/queue-6.17/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch @@ -0,0 +1,43 @@ +From def849fc138418fb72f23e1437737b03914e9743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:15 +0100 +Subject: ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97aee67e2406ea381408915e606c5f86448f3949 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f1b0ffaa686f ("ARM: dts: exynos: Enable WLAN support for the UniversalC210 board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-2-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +index bdc30f8cf748f..91490693432b6 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +@@ -610,6 +610,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&ldo5_reg>; +-- +2.51.0 + diff --git a/queue-6.17/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch b/queue-6.17/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch new file mode 100644 index 0000000000..d896e00dd2 --- /dev/null +++ b/queue-6.17/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch @@ -0,0 +1,50 @@ +From 2264f2f6db239a72e40200e84335e07cfb618c80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 00:46:11 +0200 +Subject: ARM: dts: stm32: stm32mp157c-phycore: Fix STMPE811 touchscreen node + properties + +From: Jihed Chaibi + +[ Upstream commit e40b061cd379f4897e705d17cf1b4572ad0f3963 ] + +Move st,adc-freq, st,mod-12b, st,ref-sel, and st,sample-time properties +from the touchscreen subnode to the parent touch@44 node. These properties +are defined in the st,stmpe.yaml schema for the parent node, not the +touchscreen subnode, resolving the validation error about unevaluated +properties. + +Fixes: 27538a18a4fcc ("ARM: dts: stm32: add STM32MP1-based Phytec SoM") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250915224611.169980-1-jihed.chaibi.dev@gmail.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + .../boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +index bf0c32027baf7..370b2afbf15bf 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +@@ -185,13 +185,13 @@ touch@44 { + interrupt-parent = <&gpioi>; + vio-supply = <&v3v3>; + vcc-supply = <&v3v3>; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <1>; + + touchscreen { + compatible = "st,stmpe-ts"; +- st,sample-time = <4>; +- st,mod-12b = <1>; +- st,ref-sel = <0>; +- st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch b/queue-6.17/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch new file mode 100644 index 0000000000..eb192cf802 --- /dev/null +++ b/queue-6.17/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch @@ -0,0 +1,45 @@ +From 88c5ebaf151c62e8c9e76438ad167866f30689e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 21:51:34 +0100 +Subject: arm64: dts: exynos: gs101: fix sysreg_apm reg property +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Griffin + +[ Upstream commit 4348c22a4f15dbef1314f1a353d7f053b24e9ace ] + +Both the start address and size are incorrect for the apm_sysreg DT +node. Update to match the TRM (rather than how it was defined +downstream). + +Fixes: ea89fdf24fd9 ("arm64: dts: exynos: google: Add initial Google gs101 SoC support") +Signed-off-by: Peter Griffin +Reviewed-by: André Draszik +Link: https://patch.msgid.link/20251013-automatic-clocks-v1-5-72851ee00300@linaro.org +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/exynos/google/gs101.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +index c0f8c25861a9d..668de6b2b9def 100644 +--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi ++++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +@@ -1401,9 +1401,9 @@ cmu_apm: clock-controller@17400000 { + clock-names = "oscclk"; + }; + +- sysreg_apm: syscon@174204e0 { ++ sysreg_apm: syscon@17420000 { + compatible = "google,gs101-apm-sysreg", "syscon"; +- reg = <0x174204e0 0x1000>; ++ reg = <0x17420000 0x10000>; + }; + + pmu_system_controller: system-controller@17460000 { +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch b/queue-6.17/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch new file mode 100644 index 0000000000..643641f374 --- /dev/null +++ b/queue-6.17/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch @@ -0,0 +1,38 @@ +From efa9ee76fa1ef0c847cb625cb37e0c8ec190954f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:45 -0700 +Subject: arm64: dts: freescale: imx8mp-venice-gw7905-2x: remove duplicate + usdhc1 props + +From: Tim Harvey + +[ Upstream commit 8b7e58ab4a02601a0e86e9f9701d4612038d8b29 ] + +Remove the un-intended duplicate properties from usdhc1. + +Fixes: 0d5b288c2110e ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index cbf0c9a740faa..303995a8adce8 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -423,9 +423,6 @@ &usdhc1 { + bus-width = <4>; + non-removable; + status = "okay"; +- bus-width = <4>; +- non-removable; +- status = "okay"; + }; + + /* eMMC */ +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-6.17/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..9ba19c5edb --- /dev/null +++ b/queue-6.17/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From 1ddbf9bcb94ef2752deb32a662bb4cec972f5471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 752caa38eb03b..266038fbbef97 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -351,17 +351,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch b/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch new file mode 100644 index 0000000000..8a50928058 --- /dev/null +++ b/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch @@ -0,0 +1,87 @@ +From 5e1d57f444041994925e84a194abd0b4888d73c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:51 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board sdhc1 + +From: Tim Harvey + +[ Upstream commit 9db04b310ef99b546e4240c55842e81b06b78579 ] + +SDHC1 on the GW702x SOM routes to a connector for use on a baseboard +and as such are defined in the baseboard device-trees. + +Remove it from the gw702x SOM device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 20 ------------------- + .../dts/freescale/imx8mp-venice-gw72xx.dtsi | 11 ---------- + 2 files changed, 31 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 086ee4510cd83..fb159199b39de 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -402,15 +402,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board */ +-&usdhc1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_usdhc1>; +- bus-width = <4>; +- non-removable; +- status = "okay"; +-}; +- + /* eMMC */ + &usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; +@@ -513,17 +504,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +index cf747ec6fa16e..76020ef89bf3e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +@@ -365,17 +365,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch b/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch new file mode 100644 index 0000000000..690ffd80b3 --- /dev/null +++ b/queue-6.17/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch @@ -0,0 +1,85 @@ +From f868cf2b71ba076a182f9d47541f1bd4c36e70a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:50 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board uart + +From: Tim Harvey + +[ Upstream commit effe98060f70eb96e142f656e750d6af275ceac3 ] + +UART1 and UART3 go to a connector for use on a baseboard and as such are +defined in the baseboard device-trees. Remove them from the gw702x SOM +device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 28 ------------------- + 1 file changed, 28 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 303995a8adce8..086ee4510cd83 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -395,13 +395,6 @@ &i2c3 { + status = "okay"; + }; + +-/* off-board header */ +-&uart1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart1>; +- status = "okay"; +-}; +- + /* console */ + &uart2 { + pinctrl-names = "default"; +@@ -409,13 +402,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board header */ +-&uart3 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart3>; +- status = "okay"; +-}; +- + /* off-board */ + &usdhc1 { + pinctrl-names = "default"; +@@ -520,13 +506,6 @@ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2 + >; + }; + +- pinctrl_uart1: uart1grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 +- MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 +- >; +- }; +- + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 +@@ -534,13 +513,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_uart3: uart3grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 +- MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 +- >; +- }; +- + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch b/queue-6.17/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch new file mode 100644 index 0000000000..b3494ef26d --- /dev/null +++ b/queue-6.17/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch @@ -0,0 +1,35 @@ +From e4e64a26fc216eabb4d290793a5b5811b781b4bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 10:27:04 +0800 +Subject: arm64: dts: imx95-15x15-evk: add fan-supply property for pwm-fan + +From: Joy Zou + +[ Upstream commit 93b2fac5cdaf0d501d04c9a4b0e5024632a6af7c ] + +Add fan-supply regulator to pwm-fan node to specify power source. + +Fixes: e3e8b199aff8 ("arm64: dts: imx95: Add imx95-15x15-evk support") +Signed-off-by: Joy Zou +Reviewed-by: Frank Li +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +index 46f6e0fbf2b09..29630b666d54a 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts ++++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +@@ -44,6 +44,7 @@ chosen { + + fan0: pwm-fan { + compatible = "pwm-fan"; ++ fan-supply = <®_vcc_12v>; + #cooling-cells = <2>; + cooling-levels = <64 128 192 255>; + pwms = <&tpm6 0 4000000 PWM_POLARITY_INVERTED>; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch b/queue-6.17/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch new file mode 100644 index 0000000000..1ebe11f6fd --- /dev/null +++ b/queue-6.17/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch @@ -0,0 +1,36 @@ +From 26c571d33e85bc924fb1c357386242cf0582f6d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 13:49:08 +0100 +Subject: arm64: dts: imx95-tqma9596sa: fix TPM5 pinctrl node name + +From: Markus Niebel + +[ Upstream commit 046cb64923e8c05a8fb656baffcd8c3fc67fb688 ] + +tpm4grp will be overwritten. Fix node name + +Fixes: 91d1ff322c47 ("arm64: dt: imx95: Add TQMa95xxSA") +Signed-off-by: Markus Niebel +Signed-off-by: Alexander Stein +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +index 180124cc5bce1..c3bb61ea67961 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +@@ -617,7 +617,7 @@ pinctrl_tpm4: tpm4grp { + fsl,pins = ; + }; + +- pinctrl_tpm5: tpm4grp { ++ pinctrl_tpm5: tpm5grp { + fsl,pins = ; + }; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch b/queue-6.17/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch new file mode 100644 index 0000000000..da1495ea8d --- /dev/null +++ b/queue-6.17/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch @@ -0,0 +1,37 @@ +From dc6fb1132036ee5309dbc3b507371cdfb94106ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 13:49:09 +0100 +Subject: arm64: dts: imx95-tqma9596sa: reduce maximum FlexSPI frequency to + 66MHz + +From: Alexander Stein + +[ Upstream commit 461be3802562b2d41250b40868310579a32f32c1 ] + +66 MHz is the maximum FlexPI clock frequency in normal/overdrive mode +when RXCLKSRC = 0 (Default) + +Fixes: 91d1ff322c47 ("arm64: dt: imx95: Add TQMa95xxSA") +Signed-off-by: Alexander Stein +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +index c3bb61ea67961..16c40d11d3b5d 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +@@ -115,7 +115,7 @@ &flexspi1 { + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; +- spi-max-frequency = <80000000>; ++ spi-max-frequency = <66000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + vcc-supply = <®_1v8>; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch b/queue-6.17/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch new file mode 100644 index 0000000000..4b0d07b6e3 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch @@ -0,0 +1,40 @@ +From e165d117efcc459775f7dacd7fd5da836d6b3b5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:01 +0300 +Subject: arm64: dts: qcom: msm8996: add interconnect paths to USB2 controller + +From: Dmitry Baryshkov + +[ Upstream commit 242f7558e7bf54cb63c06506f7b0630dd67d45a4 ] + +Add the missing interconnects to the USB2 host. The Fixes tag points to +the commit which broke probing of the USB host on that platform. + +Fixes: 130733a10079 ("interconnect: qcom: msm8996: Promote to core_initcall") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Acked-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-2-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index f91605de49095..8575f4aff94c2 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3496,6 +3496,9 @@ usb2: usb@76f8800 { + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + ++ interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, ++ <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; ++ interconnect-names = "usb-ddr", "apps-usb"; + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-qcm2290-add-cci-node.patch b/queue-6.17/arm64-dts-qcom-qcm2290-add-cci-node.patch new file mode 100644 index 0000000000..dd65862c3b --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-qcm2290-add-cci-node.patch @@ -0,0 +1,92 @@ +From 6bc4c6c2d1495b95fd2a128ffb2ca3a2c9959a4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Sep 2025 23:21:02 +0200 +Subject: arm64: dts: qcom: qcm2290: Add CCI node + +From: Loic Poulain + +[ Upstream commit e645096d1f6dadcead09c722a3fbc6c44a45fece ] + +Add Camera Control Interface (CCI), supporting two I2C masters. + +Signed-off-by: Loic Poulain +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250911212102.470886-2-loic.poulain@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: 67445dc8a806 ("arm64: dts: qcom: qcm2290: Fix camss register prop ordering") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm2290.dtsi | 50 +++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +index 6b7070dad3df9..4613713124f77 100644 +--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +@@ -565,6 +565,20 @@ qup_uart4_default: qup-uart4-default-state { + bias-disable; + }; + ++ cci0_default: cci0-default-state { ++ pins = "gpio22", "gpio23"; ++ function = "cci_i2c"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ ++ cci1_default: cci1-default-state { ++ pins = "gpio29", "gpio30"; ++ function = "cci_i2c"; ++ drive-strength = <2>; ++ bias-disable; ++ }; ++ + sdc1_state_on: sdc1-on-state { + clk-pins { + pins = "sdc1_clk"; +@@ -1629,6 +1643,42 @@ adreno_smmu: iommu@59a0000 { + #iommu-cells = <2>; + }; + ++ cci: cci@5c1b000 { ++ compatible = "qcom,qcm2290-cci", "qcom,msm8996-cci"; ++ reg = <0x0 0x5c1b000 0x0 0x1000>; ++ ++ interrupts = ; ++ ++ clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, <&gcc GCC_CAMSS_CCI_0_CLK>; ++ clock-names = "ahb", "cci"; ++ assigned-clocks = <&gcc GCC_CAMSS_CCI_0_CLK>; ++ assigned-clock-rates = <37500000>; ++ ++ power-domains = <&gcc GCC_CAMSS_TOP_GDSC>; ++ ++ pinctrl-0 = <&cci0_default &cci1_default>; ++ pinctrl-names = "default"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ status = "disabled"; ++ ++ cci_i2c0: i2c-bus@0 { ++ reg = <0>; ++ clock-frequency = <400000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ ++ cci_i2c1: i2c-bus@1 { ++ reg = <1>; ++ clock-frequency = <400000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ }; ++ }; ++ + camss: camss@5c6e000 { + compatible = "qcom,qcm2290-camss"; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch b/queue-6.17/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch new file mode 100644 index 0000000000..63863a5cdf --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch @@ -0,0 +1,60 @@ +From 2e7288fe4c9541898df06588f2ebc9f3e4d6e887 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:54:56 +0200 +Subject: arm64: dts: qcom: qcm2290: Fix camss register prop ordering + +From: Loic Poulain + +[ Upstream commit 67445dc8a8060309eeb7aebbc41fa0e58302fc09 ] + +The qcm2290 CAMSS node has been applied from the V4 series, but a later +version changed the order of the register property, fix it to prevent +dtb check error. + +Fixes: 2b3aef30dd9d ("arm64: dts: qcom: qcm2290: Add CAMSS node") +Signed-off-by: Loic Poulain +Link: https://lore.kernel.org/r/20250918155456.1158691-1-loic.poulain@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm2290.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +index 4613713124f77..7705ef6ebea12 100644 +--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +@@ -1679,25 +1679,25 @@ cci_i2c1: i2c-bus@1 { + }; + }; + +- camss: camss@5c6e000 { ++ camss: camss@5c11000 { + compatible = "qcom,qcm2290-camss"; + +- reg = <0x0 0x5c6e000 0x0 0x1000>, ++ reg = <0x0 0x5c11000 0x0 0x1000>, ++ <0x0 0x5c6e000 0x0 0x1000>, + <0x0 0x5c75000 0x0 0x1000>, + <0x0 0x5c52000 0x0 0x1000>, + <0x0 0x5c53000 0x0 0x1000>, + <0x0 0x5c66000 0x0 0x400>, + <0x0 0x5c68000 0x0 0x400>, +- <0x0 0x5c11000 0x0 0x1000>, + <0x0 0x5c6f000 0x0 0x4000>, + <0x0 0x5c76000 0x0 0x4000>; +- reg-names = "csid0", ++ reg-names = "top", ++ "csid0", + "csid1", + "csiphy0", + "csiphy1", + "csitpg0", + "csitpg1", +- "top", + "vfe0", + "vfe1"; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch b/queue-6.17/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch new file mode 100644 index 0000000000..99365d0f75 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch @@ -0,0 +1,39 @@ +From c214b8c5fd5310682e347b9cfbf1fa957787dd72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Sep 2025 15:57:01 +0200 +Subject: arm64: dts: qcom: qcm6490-fairphone-fp5: Add supplies to simple-fb + node + +From: Luca Weiss + +[ Upstream commit 3d4142cac46b4dde4e60908c509c4cf107067114 ] + +Add the OLED power supplies to the simple-framebuffer node, so that +the regulators don't get turned off while the simple-fb is being used. + +Fixes: c365a026155c ("arm64: dts: qcom: qcm6490-fairphone-fp5: Enable display") +Signed-off-by: Luca Weiss +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250930-sc7280-dts-misc-v1-1-5a45923ef705@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +index e115b6a52b299..82494b41bd9ac 100644 +--- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts ++++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +@@ -47,6 +47,8 @@ framebuffer0: framebuffer@a000000 { + stride = <(1224 * 4)>; + format = "a8r8g8b8"; + clocks = <&gcc GCC_DISP_HF_AXI_CLK>; ++ vci-supply = <&vreg_oled_vci>; ++ dvdd-supply = <&vreg_oled_dvdd>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch b/queue-6.17/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch new file mode 100644 index 0000000000..9bdf004baf --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch @@ -0,0 +1,43 @@ +From 347fd53639724b93663bd8070c57b99e47f7c8e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 11:06:33 +0200 +Subject: arm64: dts: qcom: qcm6490-shift-otter: Add missing reserved-memory + +From: Alexander Martinz + +[ Upstream commit f404fdcb50021fdad6bc734d69468cc777901a80 ] + +It seems we also need to reserve a region of 81 MiB called "removed_mem" +otherwise we can easily hit memory errors with higher RAM usage. + +Fixes: 249666e34c24 ("arm64: dts: qcom: add QCM6490 SHIFTphone 8") +Signed-off-by: Alexander Martinz +Reviewed-by: Konrad Dybcio +Signed-off-by: Luca Weiss +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251009-otter-further-bringup-v2-3-5bb2f4a02cea@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +index b9a0f7ac4d9c9..3fe4e8b763343 100644 +--- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts ++++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +@@ -118,6 +118,11 @@ cdsp_mem: cdsp@88f00000 { + no-map; + }; + ++ removed_mem: removed@c0000000 { ++ reg = <0x0 0xc0000000 0x0 0x5100000>; ++ no-map; ++ }; ++ + rmtfs_mem: rmtfs@f8500000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0xf8500000 0x0 0x600000>; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch b/queue-6.17/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch new file mode 100644 index 0000000000..c9d489e71f --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch @@ -0,0 +1,45 @@ +From 3a246aacda2e4570e72da30246b0489cc82e5916 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:40:40 +0530 +Subject: arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm + +From: Praveen Talari + +[ Upstream commit 9c92d36b0b1ea8b2a19dbe0416434f3491dbfaaf ] + +For BT use cases, pins are configured with pull-up state in sleep state +to avoid noise. If IRQ type is configured as level high and the GPIO line +is also in a high state, it causes continuous interrupt assertions leading +to an IRQ storm when wakeup irq enables at system suspend/runtime suspend. + +Switching to edge-triggered interrupt (IRQ_TYPE_EDGE_FALLING) resolves +this by only triggering on state transitions (high-to-low) rather than +maintaining sensitivity to the static level state, effectively preventing +the continuous interrupt condition and eliminating the wakeup IRQ storm. + +Fixes: 9380e0a1d449 ("arm64: dts: qcom: qrb2210-rb1: add Bluetooth support") +Signed-off-by: Praveen Talari +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251110101043.2108414-2-praveen.talari@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +index b2e0fc5501c1e..af29c7ed7a685 100644 +--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts ++++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +@@ -648,7 +648,7 @@ key_volp_n: key-volp-n-state { + &uart3 { + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, +- <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>; ++ <&tlmm 11 IRQ_TYPE_EDGE_FALLING>; + pinctrl-0 = <&uart3_default>; + pinctrl-1 = <&uart3_sleep>; + pinctrl-names = "default", "sleep"; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch b/queue-6.17/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch new file mode 100644 index 0000000000..d0dc1f769b --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch @@ -0,0 +1,41 @@ +From c045f9c4e92bcbf83ae1ade328f5a088a2c0a036 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Sep 2025 13:20:28 +0200 +Subject: arm64: dts: qcom: sdm845-oneplus: Correct gpio used for slider + +From: Gergo Koteles + +[ Upstream commit d7ec7d34237498fab7a6afed8da4b7139b0e387c ] + +The previous GPIO numbers were wrong. Update them to the correct +ones and fix the label. + +Fixes: 288ef8a42612 ("arm64: dts: sdm845: add oneplus6/6t devices") +Signed-off-by: Gergo Koteles +Signed-off-by: David Heidelberg +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250927-slider-correct-v1-1-fb8cc7fdcedf@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +index b118d666e535a..942e0f0d6d9bc 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +@@ -799,8 +799,8 @@ hall_sensor_default: hall-sensor-default-state { + bias-disable; + }; + +- tri_state_key_default: tri-state-key-default-state { +- pins = "gpio40", "gpio42", "gpio26"; ++ alert_slider_default: alert-slider-default-state { ++ pins = "gpio126", "gpio52", "gpio24"; + function = "gpio"; + drive-strength = <2>; + bias-disable; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch new file mode 100644 index 0000000000..0e3a8a1fc6 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch @@ -0,0 +1,39 @@ +From 10b1dd5482766fe50048012ae25c464db9a5ad4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 18:32:16 +0200 +Subject: arm64: dts: qcom: sdm845-starqltechn: Fix i2c-gpio node name + +From: Konrad Dybcio + +[ Upstream commit 6030fa06360b8b8d898b66ac156adaaf990b83cb ] + +Fix the following DT checker warning: + +$nodename:0: 'i2c21' does not match '^i2c(@.+|-[a-z0-9]+)?$' + +Fixes: 3a4600448bef ("arm64: dts: qcom: sdm845-starqltechn: add display PMIC") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251015-topic-starltechn_i2c_gpio-v1-1-6d303184ee87@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index 1807e65621ef8..1a17870dcf6d9 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -143,7 +143,7 @@ rmtfs_mem: rmtfs-mem@fde00000 { + }; + }; + +- i2c21 { ++ i2c-21 { + compatible = "i2c-gpio"; + sda-gpios = <&tlmm 127 GPIO_ACTIVE_HIGH>; + scl-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch new file mode 100644 index 0000000000..6a0f88aca0 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch @@ -0,0 +1,71 @@ +From ffd841e520008ff787b4d606acb78a80d88af091 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:13:27 +0300 +Subject: arm64: dts: qcom: sdm845-starqltechn: fix max77705 interrupts + +From: Dzmitry Sankouski + +[ Upstream commit 4372b15d89e253e40816f0bde100890cddd25a81 ] + +Since max77705 has a register, which indicates interrupt source, it acts +as an interrupt controller. + +Direct MAX77705's subdevices to use the IC's internal interrupt +controller, instead of listening to every interrupt fired by the +chip towards the host device. + +Fixes: 7a88a931d095 ("arm64: dts: qcom: sdm845-starqltechn: add max77705 PMIC") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Dzmitry Sankouski +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250926-starqltechn-correct_max77705_nodes-v5-2-c6ab35165534@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + .../boot/dts/qcom/sdm845-samsung-starqltechn.dts | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index e0d83b6344215..1807e65621ef8 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -584,11 +584,13 @@ &uart9 { + &i2c14 { + status = "okay"; + +- pmic@66 { ++ max77705: pmic@66 { + compatible = "maxim,max77705"; + reg = <0x66>; ++ #interrupt-cells = <1>; + interrupt-parent = <&pm8998_gpios>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; + pinctrl-0 = <&pmic_int_default>; + pinctrl-names = "default"; + +@@ -629,8 +631,8 @@ max77705_charger: charger@69 { + reg = <0x69>; + compatible = "maxim,max77705-charger"; + monitored-battery = <&battery>; +- interrupt-parent = <&pm8998_gpios>; +- interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&max77705>; ++ interrupts = <0>; + }; + + fuel-gauge@36 { +@@ -638,8 +640,8 @@ fuel-gauge@36 { + compatible = "maxim,max77705-battery"; + power-supplies = <&max77705_charger>; + maxim,rsns-microohm = <5000>; +- interrupt-parent = <&pm8998_gpios>; +- interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&max77705>; ++ interrupts = <2>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch new file mode 100644 index 0000000000..6f6bb5006e --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch @@ -0,0 +1,42 @@ +From 36e248a19f4249eea2ee91338f785a7b47ef7d8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:13:26 +0300 +Subject: arm64: dts: qcom: sdm845-starqltechn: remove (address|size)-cells + +From: Dzmitry Sankouski + +[ Upstream commit 4133486382364f60ea7e4f2c9070555689d9606e ] + +Drop the unused address/size-cells properties to silence the DT +checker warning: + +pmic@66 (maxim,max77705): '#address-cells', '#size-cells' do not +match any of the regexes: '^pinctrl-[0-9]+$' + +Fixes: 7a88a931d095 ("arm64: dts: qcom: sdm845-starqltechn: add max77705 PMIC") +Reviewed-by: Konrad Dybcio +Signed-off-by: Dzmitry Sankouski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250926-starqltechn-correct_max77705_nodes-v5-1-c6ab35165534@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index d686531bf4eac..016a245a97c40 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -591,8 +591,6 @@ pmic@66 { + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pmic_int_default>; + pinctrl-names = "default"; +- #address-cells = <1>; +- #size-cells = <0>; + + leds { + compatible = "maxim,max77705-rgb"; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch b/queue-6.17/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch new file mode 100644 index 0000000000..e091694d2e --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch @@ -0,0 +1,47 @@ +From 9fef8275ad0537cf6c22088692a29c7734f3bad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 20:53:44 +0200 +Subject: arm64: dts: qcom: sm8650: set ufs as dma coherent + +From: Neil Armstrong + +[ Upstream commit c2703c90161b45bca5b65f362adbae02ed71fcc1 ] + +The UFS device is ovbiously dma coherent like the other IOMMU devices +like usb, mmc, ... let's fix this by adding the flag. + +To be sure an extensive test has been performed to be sure it's +safe, as downstream uses this flag for UFS as well. + +As an experiment, I checked how the dma-coherent could impact +the UFS bandwidth, and it happens the max bandwidth on cached +write is slighly highter (up to 10%) while using less cpu time +since cache sync/flush is skipped. + +Fixes: 10e024671295 ("arm64: dts: qcom: sm8650: add interconnect dependent device nodes") +Signed-off-by: Neil Armstrong +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251007-topic-sm8650-upstream-ufs-dma-coherent-v1-1-f3cfeaee04ce@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi +index e14d3d778b71b..d7ed45027ff45 100644 +--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi +@@ -4020,6 +4020,8 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + + iommus = <&apps_smmu 0x60 0>; + ++ dma-coherent; ++ + lanes-per-direction = <2>; + qcom,ice = <&ice>; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-starqltechn-remove-extra-empty-line.patch b/queue-6.17/arm64-dts-qcom-starqltechn-remove-extra-empty-line.patch new file mode 100644 index 0000000000..b7fdd8a576 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-starqltechn-remove-extra-empty-line.patch @@ -0,0 +1,39 @@ +From 8ab2ba50d2729912f000d47a19ff3cb938e0a331 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Aug 2025 20:49:28 +0000 +Subject: arm64: dts: qcom: starqltechn: remove extra empty line +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Gonçalves + +[ Upstream commit 6e71c5812856d67881572159098f701184c9356a ] + +Remove empty white line ine starqltechn device tree at the end of +max77705_charger node. + +Signed-off-by: Eric Gonçalves +Link: https://lore.kernel.org/r/20250828204929.35402-1-ghatto404@gmail.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: 4372b15d89e2 ("arm64: dts: qcom: sdm845-starqltechn: fix max77705 interrupts") +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index 016a245a97c40..e0d83b6344215 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -631,7 +631,6 @@ max77705_charger: charger@69 { + monitored-battery = <&battery>; + interrupt-parent = <&pm8998_gpios>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; +- + }; + + fuel-gauge@36 { +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch b/queue-6.17/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch new file mode 100644 index 0000000000..8e06951486 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch @@ -0,0 +1,39 @@ +From e10ddb53aace75be4b3c310c5cd44f5863cc2420 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 16:20:18 +0530 +Subject: arm64: dts: qcom: x1e80100: Add missing quirk for HS only USB + controller + +From: Krishna Kurapati + +[ Upstream commit 6b3e8a5d6c88609d9ce93789524f818cca0aa485 ] + +The PIPE clock is provided by the USB3 PHY, which is predictably not +connected to the HS-only controller. Add "qcom,select-utmi-as-pipe-clk" +quirk to HS only USB controller to disable pipe clock requirement. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20251024105019.2220832-2-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index 2022aebf4889c..67c888ae94de5 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4859,6 +4859,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + interconnect-names = "usb-ddr", + "apps-usb"; + ++ qcom,select-utmi-as-pipe-clk; + wakeup-source; + + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch b/queue-6.17/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch new file mode 100644 index 0000000000..789d12c299 --- /dev/null +++ b/queue-6.17/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch @@ -0,0 +1,53 @@ +From 0f108b71e8773ff7bbdb68f95b4a3dc1c34bc29b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Oct 2025 17:26:30 +0530 +Subject: arm64: dts: qcom: x1e80100: Fix compile warnings for USB HS + controller + +From: Krishna Kurapati + +[ Upstream commit 0dab10c38282e6ef87ef88efb99d4106cce7ed33 ] + +With W=1, the following error comes up: + +Warning (graph_child_address): /soc@0/usb@a2f8800/usb@a200000/ports: graph node has single child node 'port@0', #address-cells/#size-cells are not necessary + +This could be since the controller is only HS capable and only one port +node is added. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251019115630.2222720-1-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index a9a7bb676c6f8..2022aebf4889c 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4876,15 +4876,8 @@ usb_2_dwc3: usb@a200000 { + + dma-coherent; + +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- +- usb_2_dwc3_hs: endpoint { +- }; ++ port { ++ usb_2_dwc3_hs: endpoint { + }; + }; + }; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch b/queue-6.17/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch new file mode 100644 index 0000000000..d866233b81 --- /dev/null +++ b/queue-6.17/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch @@ -0,0 +1,60 @@ +From 3bcbc66d24e5085688934b41b597358091edd908 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 19:45:53 +0100 +Subject: arm64: dts: renesas: sparrow-hawk: Fix full-size DP connector node + name and labels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Vasut + +[ Upstream commit 9d22a34a016313137b9e534a918f1f9aa790aa69 ] + +The DisplayPort connector on Retronix R-Car V4H Sparrow Hawk board +is a full-size DisplayPort connector. Fix the copy-paste error and +update the DT node name and labels accordingly. No functional change. + +Fixes: a719915e76f2 ("arm64: dts: renesas: r8a779g3: Add Retronix R-Car V4H Sparrow Hawk board support") +Signed-off-by: Marek Vasut +Reviewed-by: Niklas Söderlund +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251027184604.34550-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +index 2c1ab75e4d910..e5af9c056ac97 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts ++++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +@@ -118,13 +118,13 @@ memory@600000000 { + }; + + /* Page 27 / DSI to Display */ +- mini-dp-con { ++ dp-con { + compatible = "dp-connector"; + label = "CN6"; + type = "full-size"; + + port { +- mini_dp_con_in: endpoint { ++ dp_con_in: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; +@@ -371,7 +371,7 @@ sn65dsi86_in: endpoint { + port@1 { + reg = <1>; + sn65dsi86_out: endpoint { +- remote-endpoint = <&mini_dp_con_in>; ++ remote-endpoint = <&dp_con_in>; + }; + }; + }; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch b/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch new file mode 100644 index 0000000000..4900abaf43 --- /dev/null +++ b/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch @@ -0,0 +1,48 @@ +From 6a2502d2081859ec4e915edb37f347613d24c1ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:30 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 3069ff1930aa71e125874c780ffaa6caeda5800a ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is +vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1] +Describe this supply. + +[1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-3-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 53df90b0eed16..6ed8b15e6cdfd 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -226,6 +226,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcc_3v3_pmu>; + }; + }; + +@@ -593,7 +594,7 @@ regulator-state-mem { + }; + }; + +- vcc_3v3_s3: dcdc-reg8 { ++ vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12003 b/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12003 new file mode 100644 index 0000000000..57ec5d3cd5 --- /dev/null +++ b/queue-6.17/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12003 @@ -0,0 +1,38 @@ +From f33169123b66bee164cd810ad7e610054b30f3c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:31 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C + +From: FUKAUMI Naoki + +[ Upstream commit 260316d35cf8f8606c5ed7a349cc92e1e71d8150 ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is +vcca1v8_pmu. [1] Describe this supply. + +[1] https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13 + +Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-4-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +index 6224d72813e59..80ac40555e023 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +@@ -466,6 +466,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcca1v8_pmu>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch b/queue-6.17/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch new file mode 100644 index 0000000000..40e5e85dcc --- /dev/null +++ b/queue-6.17/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch @@ -0,0 +1,58 @@ +From e509b1745594ecf278b6a04d85ad43b0aaef4766 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:29 +0000 +Subject: arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa + ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 92e6e0b0e595afdda6296c760551ad3ffe9d5231 ] + +The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the +i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0 +bus. + +[1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-2-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index f894742b1ebef..53df90b0eed16 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -221,6 +221,12 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; ++ ++ eeprom: eeprom@50 { ++ compatible = "belling,bl24c16a", "atmel,24c16"; ++ reg = <0x50>; ++ pagesize = <16>; ++ }; + }; + + &i2c2 { +@@ -242,12 +248,6 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; +- +- eeprom: eeprom@50 { +- compatible = "belling,bl24c16a", "atmel,24c16"; +- reg = <0x50>; +- pagesize = <16>; +- }; + }; + + &i2c3 { +-- +2.51.0 + diff --git a/queue-6.17/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch b/queue-6.17/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch new file mode 100644 index 0000000000..b4c098e289 --- /dev/null +++ b/queue-6.17/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch @@ -0,0 +1,40 @@ +From 2ae9047050363d9c1780db5404f8688384be8ed5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 14:33:42 -0500 +Subject: arm64: dts: ti: k3-am62p: Fix memory ranges for GPU + +From: Randolph Sapp + +[ Upstream commit 76546090b1726118cd6fb3db7159fc2a3fdda8a0 ] + +Update the memory region listed in the k3-am62p.dtsi for the BXS-4-64 +GPU to match the Main Memory Map described in the TRM [1]. + +[1] https://www.ti.com/lit/ug/spruj83b/spruj83b.pdf + +Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs") +Signed-off-by: Randolph Sapp +Reviewed-by: Michael Walle +Link: https://patch.msgid.link/20250919193341.707660-2-rs@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +index 75a15c368c11b..dd24c40c7965d 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +@@ -59,7 +59,7 @@ cbass_main: bus@f0000 { + <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ + <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ +- <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ ++ <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ + <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ + <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ + <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ +-- +2.51.0 + diff --git a/queue-6.17/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-6.17/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..3baec93229 --- /dev/null +++ b/queue-6.17/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From 75f7e04ab07af7816d220b3e75ca1d26400456e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 5d804860f7d8c..58db4906a01d5 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1421,7 +1421,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, +-- +2.51.0 + diff --git a/queue-6.17/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-6.17/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..c0e5d649f5 --- /dev/null +++ b/queue-6.17/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From 15c11238dd46f8c16c436034ee341a2f4cc181b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index bf734c69c4e09..eb03cecdee281 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-6.17/asoc-nau8325-add-missing-build-config.patch b/queue-6.17/asoc-nau8325-add-missing-build-config.patch new file mode 100644 index 0000000000..883d29e433 --- /dev/null +++ b/queue-6.17/asoc-nau8325-add-missing-build-config.patch @@ -0,0 +1,70 @@ +From c373907dfa0b6bda543bc03eaed627317ffef330 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:35 +0100 +Subject: ASoC: nau8325: add missing build config + +From: Jaroslav Kysela + +[ Upstream commit cd41d3420ef658b2ca902d7677536ec8e25b610a ] + +This configuration was missing from the initial commit. + +Found by Jiri Benc + +Fixes: c0a3873b9938 ("ASoC: nau8325: new driver") +Cc: Seven Lee +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-3-perex@perex.cz +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/Kconfig | 5 +++++ + sound/soc/codecs/Makefile | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 6d7e4725d89cd..412f8710049d0 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -169,6 +169,7 @@ config SND_SOC_ALL_CODECS + imply SND_SOC_MT6359 + imply SND_SOC_MT6660 + imply SND_SOC_NAU8315 ++ imply SND_SOC_NAU8325 + imply SND_SOC_NAU8540 + imply SND_SOC_NAU8810 + imply SND_SOC_NAU8821 +@@ -2655,6 +2656,10 @@ config SND_SOC_MT6660 + config SND_SOC_NAU8315 + tristate "Nuvoton Technology Corporation NAU8315 CODEC" + ++config SND_SOC_NAU8325 ++ tristate "Nuvoton Technology Corporation NAU8325 CODEC" ++ depends on I2C ++ + config SND_SOC_NAU8540 + tristate "Nuvoton Technology Corporation NAU85L40 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index a68c3d192a1b6..53976868e6a79 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -190,6 +190,7 @@ snd-soc-mt6359-y := mt6359.o + snd-soc-mt6359-accdet-y := mt6359-accdet.o + snd-soc-mt6660-y := mt6660.o + snd-soc-nau8315-y := nau8315.o ++snd-soc-nau8325-y := nau8325.o + snd-soc-nau8540-y := nau8540.o + snd-soc-nau8810-y := nau8810.o + snd-soc-nau8821-y := nau8821.o +@@ -610,6 +611,7 @@ obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o + obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o + obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o + obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o ++obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o + obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o + obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o + obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o +-- +2.51.0 + diff --git a/queue-6.17/asoc-nau8325-use-simple-i2c-probe-function.patch b/queue-6.17/asoc-nau8325-use-simple-i2c-probe-function.patch new file mode 100644 index 0000000000..cecd683be2 --- /dev/null +++ b/queue-6.17/asoc-nau8325-use-simple-i2c-probe-function.patch @@ -0,0 +1,41 @@ +From d9d10f9e79bcda3562b333fcee703196d79d2ada Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:34 +0100 +Subject: ASoC: nau8325: use simple i2c probe function + +From: Jaroslav Kysela + +[ Upstream commit b4d072c98e47c562834f2a050ca98a1c709ef4f9 ] + +The i2c probe functions here don't use the id information provided in +their second argument, so the single-parameter i2c probe function +("probe_new") can be used instead. + +This avoids scanning the identifier tables during probes. + +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-2-perex@perex.cz +Signed-off-by: Mark Brown +Stable-dep-of: cd41d3420ef6 ("ASoC: nau8325: add missing build config") +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/nau8325.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/nau8325.c b/sound/soc/codecs/nau8325.c +index 2266f320a8f22..5b3115b0a7e58 100644 +--- a/sound/soc/codecs/nau8325.c ++++ b/sound/soc/codecs/nau8325.c +@@ -829,8 +829,7 @@ static int nau8325_read_device_properties(struct device *dev, + return 0; + } + +-static int nau8325_i2c_probe(struct i2c_client *i2c, +- const struct i2c_device_id *id) ++static int nau8325_i2c_probe(struct i2c_client *i2c) + { + struct device *dev = &i2c->dev; + struct nau8325 *nau8325 = dev_get_platdata(dev); +-- +2.51.0 + diff --git a/queue-6.17/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch b/queue-6.17/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch new file mode 100644 index 0000000000..8b09f49d55 --- /dev/null +++ b/queue-6.17/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch @@ -0,0 +1,42 @@ +From 9aef55dd304f3fe7bea26f24cb6f2c5beb72b9aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:30:11 +0000 +Subject: ASoC: SDCA: Fix missing dash in HIDE DisCo property + +From: Charles Keepax + +[ Upstream commit 3508311f2e1c872b645f13c6fd52840418089d41 ] + +The property name is "mipi-sdca-RxUMP-ownership-transition-max-delay", +with a dash between max and delay. Add the missing dash. + +Fixes: 13ef21dffe76 ("ASoC: SDCA: add support for HIDE entity properties and HID descriptor/report") +Tested-by: Bard Liao +Reviewed-by: Maciej Strozek +Reviewed-by: Peter Ujfalusi +Tested-by: Richard Fitzgerald +Signed-off-by: Charles Keepax +Link: https://patch.msgid.link/20251120153023.2105663-3-ckeepax@opensource.cirrus.com +Reviewed-by: Vinod Koul +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sdca/sdca_functions.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c +index 0ccb6775f4de3..19b12564f822e 100644 +--- a/sound/soc/sdca/sdca_functions.c ++++ b/sound/soc/sdca/sdca_functions.c +@@ -1263,7 +1263,7 @@ find_sdca_entity_hide(struct device *dev, struct fwnode_handle *function_node, + unsigned char *report_desc = NULL; + + ret = fwnode_property_read_u32(entity_node, +- "mipi-sdca-RxUMP-ownership-transition-maxdelay", &delay); ++ "mipi-sdca-RxUMP-ownership-transition-max-delay", &delay); + if (!ret) + hide->max_delay = delay; + +-- +2.51.0 + diff --git a/queue-6.17/asoc-tas2781-correct-the-wrong-period.patch b/queue-6.17/asoc-tas2781-correct-the-wrong-period.patch new file mode 100644 index 0000000000..a89bf8b0f8 --- /dev/null +++ b/queue-6.17/asoc-tas2781-correct-the-wrong-period.patch @@ -0,0 +1,37 @@ +From 0a3a48658d91c88f583ad824ea6d528d4373697f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 07:44:27 +0800 +Subject: ASoC: tas2781: correct the wrong period + +From: Shenghao Ding + +[ Upstream commit 950167a99dfd27eeaf177092908c598a31c79a7e ] + +A wrong preiod at the end of the sentence was reported by one of my +customers. Their thorough code review is greatly appreciated. + +Fixes: 49e2e353fb0d ("ASoC: tas2781: Add Calibration Kcontrols for Chromebook") +Signed-off-by: Shenghao Ding +Link: https://patch.msgid.link/20251121234427.402-1-shenghao-ding@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2781-i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c +index 9890b1a6d2924..e3a4d95b2b827 100644 +--- a/sound/soc/codecs/tas2781-i2c.c ++++ b/sound/soc/codecs/tas2781-i2c.c +@@ -1340,7 +1340,7 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) + + /* + * Alloc kcontrol via devm_kzalloc(), which don't manually +- * free the kcontrol。 ++ * free the kcontrol. + */ + cali_ctrls = devm_kcalloc(priv->dev, nctrls, + sizeof(cali_ctrls[0]), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.17/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-6.17/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..6783af7dc2 --- /dev/null +++ b/queue-6.17/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 63f0af439dcb814e447143771847c88dd82e360b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index d2db157b2c290..0ed585eb27903 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-6.17/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-6.17/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..34e01425c7 --- /dev/null +++ b/queue-6.17/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From c7e039debd750cc7d9a20f10200a34877b7ba69d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-6.17/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch b/queue-6.17/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch new file mode 100644 index 0000000000..b3baf7e68e --- /dev/null +++ b/queue-6.17/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch @@ -0,0 +1,73 @@ +From 113a870d6003b0156006c57b2e4bcd62fa823a5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:54:32 -0800 +Subject: block/blk-throttle: Fix throttle slice time for SSDs + +From: Guenter Roeck + +[ Upstream commit f76581f9f1d29e32e120b0242974ba266e79de58 ] + +Commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD") +introduced device type specific throttle slices if BLK_DEV_THROTTLING_LOW +was enabled. Commit bf20ab538c81 ("blk-throttle: remove +CONFIG_BLK_DEV_THROTTLING_LOW") removed support for BLK_DEV_THROTTLING_LOW, +but left the device type specific throttle slices in place. This +effectively changed throttling behavior on systems with SSD which now use +a different and non-configurable slice time compared to non-SSD devices. +Practical impact is that throughput tests with low configured throttle +values (65536 bps) experience less than expected throughput on SSDs, +presumably due to rounding errors associated with the small throttle slice +time used for those devices. The same tests pass when setting the throttle +values to 65536 * 4 = 262144 bps. + +The original code sets the throttle slice time to DFL_THROTL_SLICE_HD if +CONFIG_BLK_DEV_THROTTLING_LOW is disabled. Restore that code to fix the +problem. With that, DFL_THROTL_SLICE_SSD is no longer necessary. Revert to +the original code and re-introduce DFL_THROTL_SLICE to replace both +DFL_THROTL_SLICE_HD and DFL_THROTL_SLICE_SSD. This effectively reverts +commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD"). + +While at it, also remove MAX_THROTL_SLICE since it is not used anymore. + +Fixes: bf20ab538c81 ("blk-throttle: remove CONFIG_BLK_DEV_THROTTLING_LOW") +Cc: Yu Kuai +Cc: Tejun Heo +Signed-off-by: Guenter Roeck +Signed-off-by: Khazhismel Kumykov +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-throttle.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/block/blk-throttle.c b/block/blk-throttle.c +index 2c5b64b1a724a..c19d052a8f2f1 100644 +--- a/block/blk-throttle.c ++++ b/block/blk-throttle.c +@@ -22,9 +22,7 @@ + #define THROTL_QUANTUM 32 + + /* Throttling is performed over a slice and after that slice is renewed */ +-#define DFL_THROTL_SLICE_HD (HZ / 10) +-#define DFL_THROTL_SLICE_SSD (HZ / 50) +-#define MAX_THROTL_SLICE (HZ) ++#define DFL_THROTL_SLICE (HZ / 10) + + /* A workqueue to queue throttle related work */ + static struct workqueue_struct *kthrotld_workqueue; +@@ -1341,10 +1339,7 @@ static int blk_throtl_init(struct gendisk *disk) + goto out; + } + +- if (blk_queue_nonrot(q)) +- td->throtl_slice = DFL_THROTL_SLICE_SSD; +- else +- td->throtl_slice = DFL_THROTL_SLICE_HD; ++ td->throtl_slice = DFL_THROTL_SLICE; + td->track_bio_latency = !queue_is_mq(q); + if (!td->track_bio_latency) + blk_stat_enable_accounting(q); +-- +2.51.0 + diff --git a/queue-6.17/block-mq-deadline-introduce-dd_start_request.patch b/queue-6.17/block-mq-deadline-introduce-dd_start_request.patch new file mode 100644 index 0000000000..36c939d2c4 --- /dev/null +++ b/queue-6.17/block-mq-deadline-introduce-dd_start_request.patch @@ -0,0 +1,74 @@ +From 98ef32d8d5442744c15eeac7c1c42109050ec0b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:02 -0700 +Subject: block/mq-deadline: Introduce dd_start_request() + +From: Bart Van Assche + +[ Upstream commit 93a358af59c6e8ab00b57cfdb1c437516a4948ca ] + +Prepare for adding a second caller of this function. No functionality +has been changed. + +Cc: Damien Le Moal +Cc: Yu Kuai +Cc: chengkaitao +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moal +Signed-off-by: Jens Axboe +Stable-dep-of: d60055cf5270 ("block/mq-deadline: Switch back to a single dispatch list") +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 2e689b2c40213..9d449503613d6 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -310,6 +310,19 @@ static bool started_after(struct deadline_data *dd, struct request *rq, + return time_after(start_time, latest_start); + } + ++static struct request *dd_start_request(struct deadline_data *dd, ++ enum dd_data_dir data_dir, ++ struct request *rq) ++{ ++ u8 ioprio_class = dd_rq_ioclass(rq); ++ enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; ++ ++ dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); ++ dd->per_prio[prio].stats.dispatched++; ++ rq->rq_flags |= RQF_STARTED; ++ return rq; ++} ++ + /* + * deadline_dispatch_requests selects the best request according to + * read/write expire, fifo_batch, etc and with a start time <= @latest_start. +@@ -320,8 +333,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + { + struct request *rq, *next_rq; + enum dd_data_dir data_dir; +- enum dd_prio prio; +- u8 ioprio_class; + + lockdep_assert_held(&dd->lock); + +@@ -415,12 +426,7 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + dd->batching++; + deadline_move_request(dd, per_prio, rq); + done: +- ioprio_class = dd_rq_ioclass(rq); +- prio = ioprio_class_to_prio[ioprio_class]; +- dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); +- dd->per_prio[prio].stats.dispatched++; +- rq->rq_flags |= RQF_STARTED; +- return rq; ++ return dd_start_request(dd, data_dir, rq); + } + + /* +-- +2.51.0 + diff --git a/queue-6.17/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch b/queue-6.17/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch new file mode 100644 index 0000000000..6db1604591 --- /dev/null +++ b/queue-6.17/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch @@ -0,0 +1,227 @@ +From d527030c841d24cf759d4850975772e92fae2cfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:03 -0700 +Subject: block/mq-deadline: Switch back to a single dispatch list + +From: Bart Van Assche + +[ Upstream commit d60055cf52703a705b86fb25b9b7931ec7ee399c ] + +Commit c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +modified the behavior of request flag BLK_MQ_INSERT_AT_HEAD from +dispatching a request before other requests into dispatching a request +before other requests with the same I/O priority. This is not correct since +BLK_MQ_INSERT_AT_HEAD is used when requeuing requests and also when a flush +request is inserted. Both types of requests should be dispatched as soon +as possible. Hence, make the mq-deadline I/O scheduler again ignore the I/O +priority for BLK_MQ_INSERT_AT_HEAD requests. + +Cc: Damien Le Moal +Cc: Yu Kuai +Reported-by: chengkaitao +Closes: https://lore.kernel.org/linux-block/20251009155253.14611-1-pilgrimtao@gmail.com/ +Fixes: c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moalv +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 107 +++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 60 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 9d449503613d6..77250fcecb545 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -71,7 +71,6 @@ struct io_stats_per_prio { + * present on both sort_list[] and fifo_list[]. + */ + struct dd_per_prio { +- struct list_head dispatch; + struct rb_root sort_list[DD_DIR_COUNT]; + struct list_head fifo_list[DD_DIR_COUNT]; + /* Position of the most recently dispatched request. */ +@@ -84,6 +83,7 @@ struct deadline_data { + * run time data + */ + ++ struct list_head dispatch; + struct dd_per_prio per_prio[DD_PRIO_COUNT]; + + /* Data direction of latest dispatched request. */ +@@ -336,16 +336,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + + lockdep_assert_held(&dd->lock); + +- if (!list_empty(&per_prio->dispatch)) { +- rq = list_first_entry(&per_prio->dispatch, struct request, +- queuelist); +- if (started_after(dd, rq, latest_start)) +- return NULL; +- list_del_init(&rq->queuelist); +- data_dir = rq_data_dir(rq); +- goto done; +- } +- + /* + * batches are currently reads XOR writes + */ +@@ -425,7 +415,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + */ + dd->batching++; + deadline_move_request(dd, per_prio, rq); +-done: + return dd_start_request(dd, data_dir, rq); + } + +@@ -473,6 +462,14 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) + enum dd_prio prio; + + spin_lock(&dd->lock); ++ ++ if (!list_empty(&dd->dispatch)) { ++ rq = list_first_entry(&dd->dispatch, struct request, queuelist); ++ list_del_init(&rq->queuelist); ++ dd_start_request(dd, rq_data_dir(rq), rq); ++ goto unlock; ++ } ++ + rq = dd_dispatch_prio_aged_requests(dd, now); + if (rq) + goto unlock; +@@ -561,10 +558,10 @@ static int dd_init_sched(struct request_queue *q, struct elevator_queue *eq) + + eq->elevator_data = dd; + ++ INIT_LIST_HEAD(&dd->dispatch); + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + +- INIT_LIST_HEAD(&per_prio->dispatch); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_READ]); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_WRITE]); + per_prio->sort_list[DD_READ] = RB_ROOT; +@@ -668,7 +665,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + trace_block_rq_insert(rq); + + if (flags & BLK_MQ_INSERT_AT_HEAD) { +- list_add(&rq->queuelist, &per_prio->dispatch); ++ list_add(&rq->queuelist, &dd->dispatch); + rq->fifo_time = jiffies; + } else { + deadline_add_rq_rb(per_prio, rq); +@@ -735,8 +732,7 @@ static void dd_finish_request(struct request *rq) + + static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) + { +- return !list_empty_careful(&per_prio->dispatch) || +- !list_empty_careful(&per_prio->fifo_list[DD_READ]) || ++ return !list_empty_careful(&per_prio->fifo_list[DD_READ]) || + !list_empty_careful(&per_prio->fifo_list[DD_WRITE]); + } + +@@ -745,6 +741,9 @@ static bool dd_has_work(struct blk_mq_hw_ctx *hctx) + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + enum dd_prio prio; + ++ if (!list_empty_careful(&dd->dispatch)) ++ return true; ++ + for (prio = 0; prio <= DD_PRIO_MAX; prio++) + if (dd_has_work_for_prio(&dd->per_prio[prio])) + return true; +@@ -953,49 +952,39 @@ static int dd_owned_by_driver_show(void *data, struct seq_file *m) + return 0; + } + +-#define DEADLINE_DISPATCH_ATTR(prio) \ +-static void *deadline_dispatch##prio##_start(struct seq_file *m, \ +- loff_t *pos) \ +- __acquires(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- spin_lock(&dd->lock); \ +- return seq_list_start(&per_prio->dispatch, *pos); \ +-} \ +- \ +-static void *deadline_dispatch##prio##_next(struct seq_file *m, \ +- void *v, loff_t *pos) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- return seq_list_next(v, &per_prio->dispatch, pos); \ +-} \ +- \ +-static void deadline_dispatch##prio##_stop(struct seq_file *m, void *v) \ +- __releases(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- \ +- spin_unlock(&dd->lock); \ +-} \ +- \ +-static const struct seq_operations deadline_dispatch##prio##_seq_ops = { \ +- .start = deadline_dispatch##prio##_start, \ +- .next = deadline_dispatch##prio##_next, \ +- .stop = deadline_dispatch##prio##_stop, \ +- .show = blk_mq_debugfs_rq_show, \ ++static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) ++ __acquires(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_lock(&dd->lock); ++ return seq_list_start(&dd->dispatch, *pos); + } + +-DEADLINE_DISPATCH_ATTR(0); +-DEADLINE_DISPATCH_ATTR(1); +-DEADLINE_DISPATCH_ATTR(2); +-#undef DEADLINE_DISPATCH_ATTR ++static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ return seq_list_next(v, &dd->dispatch, pos); ++} ++ ++static void deadline_dispatch_stop(struct seq_file *m, void *v) ++ __releases(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_unlock(&dd->lock); ++} ++ ++static const struct seq_operations deadline_dispatch_seq_ops = { ++ .start = deadline_dispatch_start, ++ .next = deadline_dispatch_next, ++ .stop = deadline_dispatch_stop, ++ .show = blk_mq_debugfs_rq_show, ++}; + + #define DEADLINE_QUEUE_DDIR_ATTRS(name) \ + {#name "_fifo_list", 0400, \ +@@ -1018,9 +1007,7 @@ static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { + {"batching", 0400, deadline_batching_show}, + {"starved", 0400, deadline_starved_show}, + {"async_depth", 0400, dd_async_depth_show}, +- {"dispatch0", 0400, .seq_ops = &deadline_dispatch0_seq_ops}, +- {"dispatch1", 0400, .seq_ops = &deadline_dispatch1_seq_ops}, +- {"dispatch2", 0400, .seq_ops = &deadline_dispatch2_seq_ops}, ++ {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, + {"owned_by_driver", 0400, dd_owned_by_driver_show}, + {"queued", 0400, dd_queued_show}, + {}, +-- +2.51.0 + diff --git a/queue-6.17/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch b/queue-6.17/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch new file mode 100644 index 0000000000..fc6687e031 --- /dev/null +++ b/queue-6.17/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch @@ -0,0 +1,69 @@ +From 9b31698e51811edb78dacdf78f3c27efadfddad4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:23:30 -0800 +Subject: bpf: Check skb->transport_header is set in bpf_skb_check_mtu + +From: Martin KaFai Lau + +[ Upstream commit d946f3c98328171fa50ddb908593cf833587f725 ] + +The bpf_skb_check_mtu helper needs to use skb->transport_header when +the BPF_MTU_CHK_SEGS flag is used: + + bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) + +The transport_header is not always set. There is a WARN_ON_ONCE +report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + +bpf_prog_test_run is used: + +WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 + skb_gso_validate_network_len + bpf_skb_check_mtu + bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch + bpf_test_run + bpf_prog_test_run_skb + +For a normal ingress skb (not test_run), skb_reset_transport_header +is performed but there is plan to avoid setting it as described in +commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). + +This patch fixes the bpf helper by checking +skb_transport_header_was_set(). The check is done just before +skb->transport_header is used, to avoid breaking the existing bpf prog. +The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. + +Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") +Cc: Jesper Dangaard Brouer +Reported-by: Kaiyan Mei +Reported-by: Yinhao Hu +Signed-off-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index b20d5fecdbc95..47366ec94e589 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -6414,9 +6414,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, + */ + if (skb_is_gso(skb)) { + ret = BPF_MTU_CHK_RET_SUCCESS; +- if (flags & BPF_MTU_CHK_SEGS && +- !skb_gso_validate_network_len(skb, mtu)) +- ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ if (flags & BPF_MTU_CHK_SEGS) { ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ if (!skb_gso_validate_network_len(skb, mtu)) ++ ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ } + } + out: + *mtu_len = mtu; +-- +2.51.0 + diff --git a/queue-6.17/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch b/queue-6.17/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch new file mode 100644 index 0000000000..60344eb58c --- /dev/null +++ b/queue-6.17/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch @@ -0,0 +1,94 @@ +From d483d70527e44f5a66ddc026cd5e0f0994991201 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 17:27:02 +0000 +Subject: bpf: Cleanup unused func args in rqspinlock implementation + +From: Siddharth Chintamaneni + +[ Upstream commit 56b4d162392dda2365fbc1f482184a24b489d07d ] + +cleanup unused function args in check_deadlock* functions. + +Fixes: 31158ad02ddb ("rqspinlock: Add deadlock detection and recovery") +Signed-off-by: Siddharth Chintamaneni +Reviewed-by: Eduard Zingerman +Acked-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251001172702.122838-1-sidchintamaneni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/rqspinlock.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index a00561b1d3e51..21be48108e962 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -89,15 +89,14 @@ struct rqspinlock_timeout { + DEFINE_PER_CPU_ALIGNED(struct rqspinlock_held, rqspinlock_held_locks); + EXPORT_SYMBOL_GPL(rqspinlock_held_locks); + +-static bool is_lock_released(rqspinlock_t *lock, u32 mask, struct rqspinlock_timeout *ts) ++static bool is_lock_released(rqspinlock_t *lock, u32 mask) + { + if (!(atomic_read_acquire(&lock->val) & (mask))) + return true; + return false; + } + +-static noinline int check_deadlock_AA(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock_AA(rqspinlock_t *lock) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + int cnt = min(RES_NR_HELD, rqh->cnt); +@@ -118,8 +117,7 @@ static noinline int check_deadlock_AA(rqspinlock_t *lock, u32 mask, + * more locks, which reduce to ABBA). This is not exhaustive, and we rely on + * timeouts as the final line of defense. + */ +-static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + int rqh_cnt = min(RES_NR_HELD, rqh->cnt); +@@ -142,7 +140,7 @@ static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, + * Let's ensure to break out of this loop if the lock is available for + * us to potentially acquire. + */ +- if (is_lock_released(lock, mask, ts)) ++ if (is_lock_released(lock, mask)) + return 0; + + /* +@@ -198,15 +196,14 @@ static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, + return 0; + } + +-static noinline int check_deadlock(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock(rqspinlock_t *lock, u32 mask) + { + int ret; + +- ret = check_deadlock_AA(lock, mask, ts); ++ ret = check_deadlock_AA(lock); + if (ret) + return ret; +- ret = check_deadlock_ABBA(lock, mask, ts); ++ ret = check_deadlock_ABBA(lock, mask); + if (ret) + return ret; + +@@ -234,7 +231,7 @@ static noinline int check_timeout(rqspinlock_t *lock, u32 mask, + */ + if (prev + NSEC_PER_MSEC < time) { + ts->cur = time; +- return check_deadlock(lock, mask, ts); ++ return check_deadlock(lock, mask); + } + + return 0; +-- +2.51.0 + diff --git a/queue-6.17/bpf-fix-invalid-prog-stats-access-when-update_effect.patch b/queue-6.17/bpf-fix-invalid-prog-stats-access-when-update_effect.patch new file mode 100644 index 0000000000..70caeeeb35 --- /dev/null +++ b/queue-6.17/bpf-fix-invalid-prog-stats-access-when-update_effect.patch @@ -0,0 +1,91 @@ +From 826329cef09654640bbf47629d4e0340d1fd8211 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:23:43 +0000 +Subject: bpf: Fix invalid prog->stats access when update_effective_progs fails + +From: Pu Lehui + +[ Upstream commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc ] + +Syzkaller triggers an invalid memory access issue following fault +injection in update_effective_progs. The issue can be described as +follows: + +__cgroup_bpf_detach + update_effective_progs + compute_effective_progs + bpf_prog_array_alloc <-- fault inject + purge_effective_progs + /* change to dummy_bpf_prog */ + array->items[index] = &dummy_bpf_prog.prog + +---softirq start--- +__do_softirq + ... + __cgroup_bpf_run_filter_skb + __bpf_prog_run_save_cb + bpf_prog_run + stats = this_cpu_ptr(prog->stats) + /* invalid memory access */ + flags = u64_stats_update_begin_irqsave(&stats->syncp) +---softirq end--- + + static_branch_dec(&cgroup_bpf_enabled_key[atype]) + +The reason is that fault injection caused update_effective_progs to fail +and then changed the original prog into dummy_bpf_prog.prog in +purge_effective_progs. Then a softirq came, and accessing the members of +dummy_bpf_prog.prog in the softirq triggers invalid mem access. + +To fix it, skip updating stats when stats is NULL. + +Fixes: 492ecee892c2 ("bpf: enable program stats") +Signed-off-by: Pu Lehui +Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 12 +++++++----- + kernel/bpf/syscall.c | 3 +++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index 152f2fc7b65a3..70e2f5051676b 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -709,11 +709,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; +- stats = this_cpu_ptr(prog->stats); +- flags = u64_stats_update_begin_irqsave(&stats->syncp); +- u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, duration); +- u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ if (likely(prog->stats)) { ++ stats = this_cpu_ptr(prog->stats); ++ flags = u64_stats_update_begin_irqsave(&stats->syncp); ++ u64_stats_inc(&stats->cnt); ++ u64_stats_add(&stats->nsecs, duration); ++ u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ } + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 0fbfa8532c392..c7b4f597a2936 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2406,6 +2406,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) + struct bpf_prog_stats *stats; + unsigned int flags; + ++ if (unlikely(!prog->stats)) ++ return; ++ + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); +-- +2.51.0 + diff --git a/queue-6.17/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch b/queue-6.17/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch new file mode 100644 index 0000000000..d5cfefa8e4 --- /dev/null +++ b/queue-6.17/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch @@ -0,0 +1,83 @@ +From 61d586d9bd6ff153bda046d29d217c3d30a0c400 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:29:41 +0000 +Subject: bpf: Fix stackmap overflow check in __bpf_get_stackid() + +From: Arnaud Lecomte + +[ Upstream commit 23f852daa4bab4d579110e034e4d513f7d490846 ] + +Syzkaller reported a KASAN slab-out-of-bounds write in __bpf_get_stackid() +when copying stack trace data. The issue occurs when the perf trace + contains more stack entries than the stack map bucket can hold, + leading to an out-of-bounds write in the bucket's data array. + +Fixes: ee2a098851bf ("bpf: Adjust BPF stack helper functions to accommodate skip > 0") +Reported-by: syzbot+c9b724fbb41cf2538b7b@syzkaller.appspotmail.com +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192941.1500-1-contact@arnaud-lcm.com + +Closes: https://syzkaller.appspot.com/bug?extid=c9b724fbb41cf2538b7b +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index d6027bac61c35..4abb01f281fe4 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -251,8 +251,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + { + struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map); + struct stack_map_bucket *bucket, *new_bucket, *old_bucket; ++ u32 hash, id, trace_nr, trace_len, i, max_depth; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +- u32 hash, id, trace_nr, trace_len, i; + bool user = flags & BPF_F_USER_STACK; + u64 *ips; + bool hash_matches; +@@ -261,7 +261,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + /* skipping more than usable stack trace */ + return -EFAULT; + +- trace_nr = trace->nr - skip; ++ max_depth = stack_map_calculate_max_depth(map->value_size, stack_map_data_size(map), flags); ++ trace_nr = min_t(u32, trace->nr - skip, max_depth - skip); + trace_len = trace_nr * sizeof(u64); + ips = trace->ip + skip; + hash = jhash2((u32 *)ips, trace_len / sizeof(u32), 0); +@@ -390,15 +391,11 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + return -EFAULT; + + nr_kernel = count_kernel_ip(trace); ++ __u64 nr = trace->nr; /* save original */ + + if (kernel) { +- __u64 nr = trace->nr; +- + trace->nr = nr_kernel; + ret = __bpf_get_stackid(map, trace, flags); +- +- /* restore nr */ +- trace->nr = nr; + } else { /* user */ + u64 skip = flags & BPF_F_SKIP_FIELD_MASK; + +@@ -409,6 +406,10 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + flags = (flags & ~BPF_F_SKIP_FIELD_MASK) | skip; + ret = __bpf_get_stackid(map, trace, flags); + } ++ ++ /* restore nr */ ++ trace->nr = nr; ++ + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/bpf-free-special-fields-when-update-lru_-percpu_hash.patch b/queue-6.17/bpf-free-special-fields-when-update-lru_-percpu_hash.patch new file mode 100644 index 0000000000..a0fb25dc58 --- /dev/null +++ b/queue-6.17/bpf-free-special-fields-when-update-lru_-percpu_hash.patch @@ -0,0 +1,58 @@ +From 4df9ff29d7703c5b0900c3d5c6420d2c9f7bfad2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 23:14:06 +0800 +Subject: bpf: Free special fields when update [lru_,]percpu_hash maps + +From: Leon Hwang + +[ Upstream commit 6af6e49a76c9af7d42eb923703e7648cb2bf401a ] + +As [lru_,]percpu_hash maps support BPF_KPTR_{REF,PERCPU}, missing +calls to 'bpf_obj_free_fields()' in 'pcpu_copy_value()' could cause the +memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the +map gets freed. + +Fix this by calling 'bpf_obj_free_fields()' after +'copy_map_value[,_long]()' in 'pcpu_copy_value()'. + +Fixes: 65334e64a493 ("bpf: Support kptrs in percpu hashmap and percpu LRU hashmap") +Signed-off-by: Leon Hwang +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20251105151407.12723-2-leon.hwang@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 71f9931ac64cd..f3bc22ea503fd 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -939,15 +939,21 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) + static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, + void *value, bool onallcpus) + { ++ void *ptr; ++ + if (!onallcpus) { + /* copy true value_size bytes */ +- copy_map_value(&htab->map, this_cpu_ptr(pptr), value); ++ ptr = this_cpu_ptr(pptr); ++ copy_map_value(&htab->map, ptr, value); ++ bpf_obj_free_fields(htab->map.record, ptr); + } else { + u32 size = round_up(htab->map.value_size, 8); + int off = 0, cpu; + + for_each_possible_cpu(cpu) { +- copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value + off); ++ ptr = per_cpu_ptr(pptr, cpu); ++ copy_map_value_long(&htab->map, ptr, value + off); ++ bpf_obj_free_fields(htab->map.record, ptr); + off += size; + } + } +-- +2.51.0 + diff --git a/queue-6.17/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch b/queue-6.17/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch new file mode 100644 index 0000000000..7a66dedcb7 --- /dev/null +++ b/queue-6.17/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch @@ -0,0 +1,40 @@ +From 6b1608b2c17afe36aa47942a8ac8ce77cab18b0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:07:05 +0800 +Subject: bpf: Handle return value of ftrace_set_filter_ip in register_fentry + +From: Menglong Dong + +[ Upstream commit fea3f5e83c5cd80a76d97343023a2f2e6bd862bf ] + +The error that returned by ftrace_set_filter_ip() in register_fentry() is +not handled properly. Just fix it. + +Fixes: 00963a2e75a8 ("bpf: Support bpf_trampoline on functions with IPMODIFY (e.g. livepatch)") +Signed-off-by: Menglong Dong +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251110120705.1553694-1-dongml2@chinatelecom.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/trampoline.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index 0db5673812108..1ce8696f6f6d9 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -220,7 +220,9 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr) + } + + if (tr->func.ftrace_managed) { +- ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ if (ret) ++ return ret; + ret = register_ftrace_direct(tr->fops, (long)new_addr); + } else { + ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); +-- +2.51.0 + diff --git a/queue-6.17/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch b/queue-6.17/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch new file mode 100644 index 0000000000..d0a63c160e --- /dev/null +++ b/queue-6.17/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch @@ -0,0 +1,63 @@ +From 2da5d17408284a2d586fec0006e2e48a06f93b81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:19:22 +0530 +Subject: bpf: Prevent nesting overflow in bpf_try_get_buffers + +From: Sahil Chandna + +[ Upstream commit c1da3df7191f1b4df9256bcd30d78f78201e1d17 ] + +bpf_try_get_buffers() returns one of multiple per-CPU buffers based on a +per-CPU nesting counter. This mechanism expects that buffers are not +endlessly acquired before being returned. migrate_disable() ensures that a +task remains on the same CPU, but it does not prevent the task from being +preempted by another task on that CPU. + +Without disabled preemption, a task may be preempted while holding a +buffer, allowing another task to run on same CPU and acquire an +additional buffer. Several such preemptions can cause the per-CPU +nest counter to exceed MAX_BPRINTF_NEST_LEVEL and trigger the warning in +bpf_try_get_buffers(). Adding preempt_disable()/preempt_enable() around +buffer acquisition and release prevents this task preemption and +preserves the intended bounded nesting behavior. + +Reported-by: syzbot+b0cff308140f79a9c4cb@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68f6a4c8.050a0220.1be48.0011.GAE@google.com/ +Fixes: 4223bf833c849 ("bpf: Remove preempt_disable in bpf_try_get_buffers") +Suggested-by: Yonghong Song +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: Sahil Chandna +Link: https://lore.kernel.org/r/20251114064922.11650-1-chandna.sahil@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/helpers.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index 3eb02ce0dba3b..722314912ba8f 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -774,9 +774,11 @@ int bpf_try_get_buffers(struct bpf_bprintf_buffers **bufs) + { + int nest_level; + ++ preempt_disable(); + nest_level = this_cpu_inc_return(bpf_bprintf_nest_level); + if (WARN_ON_ONCE(nest_level > MAX_BPRINTF_NEST_LEVEL)) { + this_cpu_dec(bpf_bprintf_nest_level); ++ preempt_enable(); + return -EBUSY; + } + *bufs = this_cpu_ptr(&bpf_bprintf_bufs[nest_level - 1]); +@@ -789,6 +791,7 @@ void bpf_put_buffers(void) + if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0)) + return; + this_cpu_dec(bpf_bprintf_nest_level); ++ preempt_enable(); + } + + void bpf_bprintf_cleanup(struct bpf_bprintf_data *data) +-- +2.51.0 + diff --git a/queue-6.17/bpf-refactor-stack-map-trace-depth-calculation-into-.patch b/queue-6.17/bpf-refactor-stack-map-trace-depth-calculation-into-.patch new file mode 100644 index 0000000000..a67f7daa5d --- /dev/null +++ b/queue-6.17/bpf-refactor-stack-map-trace-depth-calculation-into-.patch @@ -0,0 +1,135 @@ +From b6a45e72b5d00c9a99d8d43360bada45d4eadbed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:28:58 +0000 +Subject: bpf: Refactor stack map trace depth calculation into helper function + +From: Arnaud Lecomte + +[ Upstream commit e17d62fedd10ae56e2426858bd0757da544dbc73 ] + +Extract the duplicated maximum allowed depth computation for stack +traces stored in BPF stacks from bpf_get_stackid() and __bpf_get_stack() +into a dedicated stack_map_calculate_max_depth() helper function. + +This unifies the logic for: +- The max depth computation +- Enforcing the sysctl_perf_event_max_stack limit + +No functional changes for existing code paths. + +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192858.31424-1-contact@arnaud-lcm.com +Stable-dep-of: 23f852daa4ba ("bpf: Fix stackmap overflow check in __bpf_get_stackid()") +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 47 +++++++++++++++++++++++++++++-------------- + 1 file changed, 32 insertions(+), 15 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index ec3a57a5fba1f..d6027bac61c35 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -42,6 +42,28 @@ static inline int stack_map_data_size(struct bpf_map *map) + sizeof(struct bpf_stack_build_id) : sizeof(u64); + } + ++/** ++ * stack_map_calculate_max_depth - Calculate maximum allowed stack trace depth ++ * @size: Size of the buffer/map value in bytes ++ * @elem_size: Size of each stack trace element ++ * @flags: BPF stack trace flags (BPF_F_USER_STACK, BPF_F_USER_BUILD_ID, ...) ++ * ++ * Return: Maximum number of stack trace entries that can be safely stored ++ */ ++static u32 stack_map_calculate_max_depth(u32 size, u32 elem_size, u64 flags) ++{ ++ u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 max_depth; ++ u32 curr_sysctl_max_stack = READ_ONCE(sysctl_perf_event_max_stack); ++ ++ max_depth = size / elem_size; ++ max_depth += skip; ++ if (max_depth > curr_sysctl_max_stack) ++ return curr_sysctl_max_stack; ++ ++ return max_depth; ++} ++ + static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) + { + u64 elem_size = sizeof(struct stack_map_bucket) + +@@ -300,20 +322,17 @@ static long __bpf_get_stackid(struct bpf_map *map, + BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, + u64, flags) + { +- u32 max_depth = map->value_size / stack_map_data_size(map); +- u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 elem_size = stack_map_data_size(map); + bool user = flags & BPF_F_USER_STACK; + struct perf_callchain_entry *trace; + bool kernel = !user; ++ u32 max_depth; + + if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK | + BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) + return -EINVAL; + +- max_depth += skip; +- if (max_depth > sysctl_perf_event_max_stack) +- max_depth = sysctl_perf_event_max_stack; +- ++ max_depth = stack_map_calculate_max_depth(map->value_size, elem_size, flags); + trace = get_perf_callchain(regs, kernel, user, max_depth, + false, false); + +@@ -406,7 +425,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + struct perf_callchain_entry *trace_in, + void *buf, u32 size, u64 flags, bool may_fault) + { +- u32 trace_nr, copy_len, elem_size, num_elem, max_depth; ++ u32 trace_nr, copy_len, elem_size, max_depth; + bool user_build_id = flags & BPF_F_USER_BUILD_ID; + bool crosstask = task && task != current; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +@@ -438,21 +457,20 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + goto clear; + } + +- num_elem = size / elem_size; +- max_depth = num_elem + skip; +- if (sysctl_perf_event_max_stack < max_depth) +- max_depth = sysctl_perf_event_max_stack; ++ max_depth = stack_map_calculate_max_depth(size, elem_size, flags); + + if (may_fault) + rcu_read_lock(); /* need RCU for perf's callchain below */ + +- if (trace_in) ++ if (trace_in) { + trace = trace_in; +- else if (kernel && task) ++ trace->nr = min_t(u32, trace->nr, max_depth); ++ } else if (kernel && task) { + trace = get_callchain_entry_for_task(task, max_depth); +- else ++ } else { + trace = get_perf_callchain(regs, kernel, user, max_depth, + crosstask, false); ++ } + + if (unlikely(!trace) || trace->nr < skip) { + if (may_fault) +@@ -461,7 +479,6 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + } + + trace_nr = trace->nr - skip; +- trace_nr = (trace_nr <= num_elem) ? trace_nr : num_elem; + copy_len = trace_nr * elem_size; + + ips = trace->ip + skip; +-- +2.51.0 + diff --git a/queue-6.17/btrfs-fix-double-free-of-qgroup-record-after-failure.patch b/queue-6.17/btrfs-fix-double-free-of-qgroup-record-after-failure.patch new file mode 100644 index 0000000000..47ba8cdc1f --- /dev/null +++ b/queue-6.17/btrfs-fix-double-free-of-qgroup-record-after-failure.patch @@ -0,0 +1,155 @@ +From de0b0677f83921b954e90112854d49672efe72e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 20:05:03 +0200 +Subject: btrfs: fix double free of qgroup record after failure to add delayed + ref head +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Miquel Sabaté Solà + +[ Upstream commit 725e46298876a2cc1f1c3fb22ba69d29102c3ddf ] + +In the previous code it was possible to incur into a double kfree() +scenario when calling add_delayed_ref_head(). This could happen if the +record was reported to already exist in the +btrfs_qgroup_trace_extent_nolock() call, but then there was an error +later on add_delayed_ref_head(). In this case, since +add_delayed_ref_head() returned an error, the caller went to free the +record. Since add_delayed_ref_head() couldn't set this kfree'd pointer +to NULL, then kfree() would have acted on a non-NULL 'record' object +which was pointing to memory already freed by the callee. + +The problem comes from the fact that the responsibility to kfree the +object is on both the caller and the callee at the same time. Hence, the +fix for this is to shift the ownership of the 'qrecord' object out of +the add_delayed_ref_head(). That is, we will never attempt to kfree() +the given object inside of this function, and will expect the caller to +act on the 'qrecord' object on its own. The only exception where the +'qrecord' object cannot be kfree'd is if it was inserted into the +tracing logic, for which we already have the 'qrecord_inserted_ret' +boolean to account for this. Hence, the caller has to kfree the object +only if add_delayed_ref_head() reports not to have inserted it on the +tracing logic. + +As a side-effect of the above, we must guarantee that +'qrecord_inserted_ret' is properly initialized at the start of the +function, not at the end, and then set when an actual insert +happens. This way we avoid 'qrecord_inserted_ret' having an invalid +value on an early exit. + +The documentation from the add_delayed_ref_head() has also been updated +to reflect on the exact ownership of the 'qrecord' object. + +Fixes: 6ef8fbce0104 ("btrfs: fix missing error handling when adding delayed ref with qgroups enabled") +Reviewed-by: Filipe Manana +Signed-off-by: Miquel Sabaté Solà +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/delayed-ref.c | 43 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c +index ca382c5b186f4..39c7ad1231675 100644 +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -798,9 +798,13 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref, + } + + /* +- * helper function to actually insert a head node into the rbtree. +- * this does all the dirty work in terms of maintaining the correct +- * overall modification count. ++ * Helper function to actually insert a head node into the xarray. This does all ++ * the dirty work in terms of maintaining the correct overall modification ++ * count. ++ * ++ * The caller is responsible for calling kfree() on @qrecord. More specifically, ++ * if this function reports that it did not insert it as noted in ++ * @qrecord_inserted_ret, then it's safe to call kfree() on it. + * + * Returns an error pointer in case of an error. + */ +@@ -814,7 +818,14 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + struct btrfs_delayed_ref_head *existing; + struct btrfs_delayed_ref_root *delayed_refs; + const unsigned long index = (head_ref->bytenr >> fs_info->sectorsize_bits); +- bool qrecord_inserted = false; ++ ++ /* ++ * If 'qrecord_inserted_ret' is provided, then the first thing we need ++ * to do is to initialize it to false just in case we have an exit ++ * before trying to insert the record. ++ */ ++ if (qrecord_inserted_ret) ++ *qrecord_inserted_ret = false; + + delayed_refs = &trans->transaction->delayed_refs; + lockdep_assert_held(&delayed_refs->lock); +@@ -833,6 +844,12 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + + /* Record qgroup extent info if provided */ + if (qrecord) { ++ /* ++ * Setting 'qrecord' but not 'qrecord_inserted_ret' will likely ++ * result in a memory leakage. ++ */ ++ ASSERT(qrecord_inserted_ret != NULL); ++ + int ret; + + ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, qrecord, +@@ -840,12 +857,10 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + if (ret) { + /* Clean up if insertion fails or item exists. */ + xa_release(&delayed_refs->dirty_extents, index); +- /* Caller responsible for freeing qrecord on error. */ + if (ret < 0) + return ERR_PTR(ret); +- kfree(qrecord); +- } else { +- qrecord_inserted = true; ++ } else if (qrecord_inserted_ret) { ++ *qrecord_inserted_ret = true; + } + } + +@@ -888,8 +903,6 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + delayed_refs->num_heads++; + delayed_refs->num_heads_ready++; + } +- if (qrecord_inserted_ret) +- *qrecord_inserted_ret = qrecord_inserted; + + return head_ref; + } +@@ -1049,6 +1062,14 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, + xa_release(&delayed_refs->head_refs, index); + spin_unlock(&delayed_refs->lock); + ret = PTR_ERR(new_head_ref); ++ ++ /* ++ * It's only safe to call kfree() on 'qrecord' if ++ * add_delayed_ref_head() has _not_ inserted it for ++ * tracing. Otherwise we need to handle this here. ++ */ ++ if (!qrecord_reserved || qrecord_inserted) ++ goto free_head_ref; + goto free_record; + } + head_ref = new_head_ref; +@@ -1071,6 +1092,8 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, + + if (qrecord_inserted) + return btrfs_qgroup_trace_extent_post(trans, record, generic_ref->bytenr); ++ ++ kfree(record); + return 0; + + free_record: +-- +2.51.0 + diff --git a/queue-6.17/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch b/queue-6.17/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch new file mode 100644 index 0000000000..78571e99a8 --- /dev/null +++ b/queue-6.17/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch @@ -0,0 +1,41 @@ +From 6d175ed7df7d20fdef1a493dee6eb4b8aaacb386 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:45 +0000 +Subject: btrfs: fix leaf leak in an error path in btrfs_del_items() + +From: Filipe Manana + +[ Upstream commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 ] + +If the call to btrfs_del_leaf() fails we return without decrementing the +extra ref we took on the leaf, therefore leaking it. Fix this by ensuring +we drop the ref count before returning the error. + +Fixes: 751a27615dda ("btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr()") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 74e6d7f3d2660..47776c4487bcd 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -4557,9 +4557,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + if (btrfs_header_nritems(leaf) == 0) { + path->slots[1] = slot; + ret = btrfs_del_leaf(trans, root, path, leaf); ++ free_extent_buffer(leaf); + if (ret < 0) + return ret; +- free_extent_buffer(leaf); + ret = 0; + } else { + /* if we're still in the path, make sure +-- +2.51.0 + diff --git a/queue-6.17/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch b/queue-6.17/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch new file mode 100644 index 0000000000..70482028b3 --- /dev/null +++ b/queue-6.17/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch @@ -0,0 +1,255 @@ +From a155beb5602689758872048102d0ce934daefdaf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 17:20:22 -0700 +Subject: btrfs: fix racy bitfield write in btrfs_clear_space_info_full() + +From: Boris Burkov + +[ Upstream commit 38e818718c5e04961eea0fa8feff3f100ce40408 ] + +From the memory-barriers.txt document regarding memory barrier ordering +guarantees: + + (*) These guarantees do not apply to bitfields, because compilers often + generate code to modify these using non-atomic read-modify-write + sequences. Do not attempt to use bitfields to synchronize parallel + algorithms. + + (*) Even in cases where bitfields are protected by locks, all fields + in a given bitfield must be protected by one lock. If two fields + in a given bitfield are protected by different locks, the compiler's + non-atomic read-modify-write sequences can cause an update to one + field to corrupt the value of an adjacent field. + +btrfs_space_info has a bitfield sharing an underlying word consisting of +the fields full, chunk_alloc, and flush: + +struct btrfs_space_info { + struct btrfs_fs_info * fs_info; /* 0 8 */ + struct btrfs_space_info * parent; /* 8 8 */ + ... + int clamp; /* 172 4 */ + unsigned int full:1; /* 176: 0 4 */ + unsigned int chunk_alloc:1; /* 176: 1 4 */ + unsigned int flush:1; /* 176: 2 4 */ + ... + +Therefore, to be safe from parallel read-modify-writes losing a write to +one of the bitfield members protected by a lock, all writes to all the +bitfields must use the lock. They almost universally do, except for +btrfs_clear_space_info_full() which iterates over the space_infos and +writes out found->full = 0 without a lock. + +Imagine that we have one thread completing a transaction in which we +finished deleting a block_group and are thus calling +btrfs_clear_space_info_full() while simultaneously the data reclaim +ticket infrastructure is running do_async_reclaim_data_space(): + + T1 T2 +btrfs_commit_transaction + btrfs_clear_space_info_full + data_sinfo->full = 0 + READ: full:0, chunk_alloc:0, flush:1 + do_async_reclaim_data_space(data_sinfo) + spin_lock(&space_info->lock); + if(list_empty(tickets)) + space_info->flush = 0; + READ: full: 0, chunk_alloc:0, flush:1 + MOD/WRITE: full: 0, chunk_alloc:0, flush:0 + spin_unlock(&space_info->lock); + return; + MOD/WRITE: full:0, chunk_alloc:0, flush:1 + +and now data_sinfo->flush is 1 but the reclaim worker has exited. This +breaks the invariant that flush is 0 iff there is no work queued or +running. Once this invariant is violated, future allocations that go +into __reserve_bytes() will add tickets to space_info->tickets but will +see space_info->flush is set to 1 and not queue the work. After this, +they will block forever on the resulting ticket, as it is now impossible +to kick the worker again. + +I also confirmed by looking at the assembly of the affected kernel that +it is doing RMW operations. For example, to set the flush (3rd) bit to 0, +the assembly is: + andb $0xfb,0x60(%rbx) +and similarly for setting the full (1st) bit to 0: + andb $0xfe,-0x20(%rax) + +So I think this is really a bug on practical systems. I have observed +a number of systems in this exact state, but am currently unable to +reproduce it. + +Rather than leaving this footgun lying around for the future, take +advantage of the fact that there is room in the struct anyway, and that +it is already quite large and simply change the three bitfield members to +bools. This avoids writes to space_info->full having any effect on +writes to space_info->flush, regardless of locking. + +Fixes: 957780eb2788 ("Btrfs: introduce ticketed enospc infrastructure") +Reviewed-by: Qu Wenruo +Signed-off-by: Boris Burkov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 6 +++--- + fs/btrfs/space-info.c | 22 +++++++++++----------- + fs/btrfs/space-info.h | 6 +++--- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 499a9edf0ca31..a368d6ac98ede 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -4215,7 +4215,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + mutex_unlock(&fs_info->chunk_mutex); + } else { + /* Proceed with allocation */ +- space_info->chunk_alloc = 1; ++ space_info->chunk_alloc = true; + wait_for_alloc = false; + spin_unlock(&space_info->lock); + } +@@ -4264,7 +4264,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + spin_lock(&space_info->lock); + if (ret < 0) { + if (ret == -ENOSPC) +- space_info->full = 1; ++ space_info->full = true; + else + goto out; + } else { +@@ -4274,7 +4274,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + + space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; + out: +- space_info->chunk_alloc = 0; ++ space_info->chunk_alloc = false; + spin_unlock(&space_info->lock); + mutex_unlock(&fs_info->chunk_mutex); + +diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c +index 0481c693ac2ea..b05ab1122a42a 100644 +--- a/fs/btrfs/space-info.c ++++ b/fs/btrfs/space-info.c +@@ -192,7 +192,7 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info) + struct btrfs_space_info *found; + + list_for_each_entry(found, head, list) +- found->full = 0; ++ found->full = false; + } + + /* +@@ -372,7 +372,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, + space_info->bytes_readonly += block_group->bytes_super; + btrfs_space_info_update_bytes_zone_unusable(space_info, block_group->zone_unusable); + if (block_group->length > 0) +- space_info->full = 0; ++ space_info->full = false; + btrfs_try_granting_tickets(info, space_info); + spin_unlock(&space_info->lock); + +@@ -1146,7 +1146,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + spin_lock(&space_info->lock); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info); + if (!to_reclaim) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1158,7 +1158,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + flush_space(fs_info, space_info, to_reclaim, flush_state, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1201,7 +1201,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + flush_state = FLUSH_DELAYED_ITEMS_NR; + commit_cycles--; + } else { +- space_info->flush = 0; ++ space_info->flush = false; + } + } else { + flush_state = FLUSH_DELAYED_ITEMS_NR; +@@ -1383,7 +1383,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1394,7 +1394,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + flush_space(fs_info, space_info, U64_MAX, ALLOC_CHUNK_FORCE, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1411,7 +1411,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + data_flush_states[flush_state], false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1428,7 +1428,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + if (maybe_fail_all_tickets(fs_info, space_info)) + flush_state = 0; + else +- space_info->flush = 0; ++ space_info->flush = false; + } else { + flush_state = 0; + } +@@ -1444,7 +1444,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + + aborted_fs: + maybe_fail_all_tickets(fs_info, space_info); +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + } + +@@ -1825,7 +1825,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info, + */ + maybe_clamp_preempt(fs_info, space_info); + +- space_info->flush = 1; ++ space_info->flush = true; + trace_btrfs_trigger_flush(fs_info, + space_info->flags, + orig_bytes, flush, +diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h +index 679f22efb4073..a846f63585c95 100644 +--- a/fs/btrfs/space-info.h ++++ b/fs/btrfs/space-info.h +@@ -142,11 +142,11 @@ struct btrfs_space_info { + flushing. The value is >> clamp, so turns + out to be a 2^clamp divisor. */ + +- unsigned int full:1; /* indicates that we cannot allocate any more ++ bool full; /* indicates that we cannot allocate any more + chunks for this space */ +- unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ ++ bool chunk_alloc; /* set if we are allocating a chunk */ + +- unsigned int flush:1; /* set if we are trying to make space */ ++ bool flush; /* set if we are trying to make space */ + + unsigned int force_alloc; /* set if we need to force a chunk + alloc for this space */ +-- +2.51.0 + diff --git a/queue-6.17/cleanup-fix-scoped_class.patch b/queue-6.17/cleanup-fix-scoped_class.patch new file mode 100644 index 0000000000..b45496a8ca --- /dev/null +++ b/queue-6.17/cleanup-fix-scoped_class.patch @@ -0,0 +1,57 @@ +From e1316ddb5eac7c99189524768492931602362b86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 00:12:40 +0100 +Subject: cleanup: fix scoped_class() + +From: Christian Brauner + +[ Upstream commit 4e97bae1b412cd6ed8053b3d8a242122952985cc ] + +This is a class, not a guard so why on earth is it checking for guard +pointers or conditional lock acquisition? None of it makes any sense at +all. + +I'm not sure what happened back then. Maybe I had a brief psychedelic +period that I completely forgot about and spaced out into a zone where +that initial macro implementation made any sense at all. + +Link: https://patch.msgid.link/20251103-work-creds-init_cred-v1-1-cb3ec8711a6a@kernel.org +Fixes: 5c21c5f22d07 ("cleanup: add a scoped version of CLASS()") +Reviewed-by: Jens Axboe +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + include/linux/cleanup.h | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index 2573585b7f068..19c7e475d3a4d 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -290,15 +290,16 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + class_##_name##_t var __cleanup(class_##_name##_destructor) = \ + class_##_name##_constructor + +-#define scoped_class(_name, var, args) \ +- for (CLASS(_name, var)(args); \ +- __guard_ptr(_name)(&var) || !__is_cond_ptr(_name); \ +- ({ goto _label; })) \ +- if (0) { \ +-_label: \ +- break; \ ++#define __scoped_class(_name, var, _label, args...) \ ++ for (CLASS(_name, var)(args); ; ({ goto _label; })) \ ++ if (0) { \ ++_label: \ ++ break; \ + } else + ++#define scoped_class(_name, var, args...) \ ++ __scoped_class(_name, var, __UNIQUE_ID(label), args) ++ + /* + * DEFINE_GUARD(name, type, lock, unlock): + * trivial wrapper around DEFINE_CLASS() above specifically +-- +2.51.0 + diff --git a/queue-6.17/clk-keystone-fix-compile-testing.patch b/queue-6.17/clk-keystone-fix-compile-testing.patch new file mode 100644 index 0000000000..07c2ace0dc --- /dev/null +++ b/queue-6.17/clk-keystone-fix-compile-testing.patch @@ -0,0 +1,41 @@ +From 47649c426064cf32322d9399db627b1d039bca48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:53:25 +0100 +Subject: clk: keystone: fix compile testing + +From: Johan Hovold + +[ Upstream commit b276445e98fe28609688fb85b89a81b803910e63 ] + +Some keystone clock drivers can be selected when COMPILE_TEST is +enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk +driver support") they are never actually built. + +Enable compile testing by allowing the build system to process the +keystone drivers. + +Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") +Signed-off-by: Johan Hovold +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/Makefile | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 18ed29cfdc113..12b4688131f11 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -124,8 +124,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ + obj-y += imgtec/ + obj-y += imx/ + obj-y += ingenic/ +-obj-$(CONFIG_ARCH_K3) += keystone/ +-obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ ++obj-y += keystone/ + obj-y += mediatek/ + obj-$(CONFIG_ARCH_MESON) += meson/ + obj-y += microchip/ +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch b/queue-6.17/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..7e9aa3ac01 --- /dev/null +++ b/queue-6.17/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch @@ -0,0 +1,53 @@ +From 52382de6ee9fc9481045900497c1dc97d7bc07cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:54 +0200 +Subject: clk: qcom: camcc-sm6350: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit ab0e13141d679fdffdd3463a272c5c1b10be1794 ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly, and fixes +CAMCC_MCLK* being stuck off. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 6c272f7b07219..7df12c1311c68 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -145,15 +145,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, + .alpha = 0x0, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), +- .early_output_mask = BIT(3), + .config_ctl_val = 0x20000800, + .config_ctl_hi_val = 0x400003d2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x00004000, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch b/queue-6.17/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..fa16ddaced --- /dev/null +++ b/queue-6.17/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,89 @@ +From 7eef8a3347da0ec0ba7a14319796f3b2a7b8adf8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:46 +0300 +Subject: clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit a76ce61d7225934b0a52c8172a8cd944002a8c6f ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM6350 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 8aac97d29ce3f..6c272f7b07219 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -1693,6 +1693,8 @@ static struct clk_branch camcc_sys_tmr_clk = { + }, + }; + ++static struct gdsc titan_top_gdsc; ++ + static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .en_rest_wait_val = 0x2, +@@ -1702,6 +1704,7 @@ static struct gdsc bps_gdsc = { + .name = "bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1714,6 +1717,7 @@ static struct gdsc ipe_0_gdsc = { + .name = "ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1726,6 +1730,7 @@ static struct gdsc ife_0_gdsc = { + .name = "ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_1_gdsc = { +@@ -1737,6 +1742,7 @@ static struct gdsc ife_1_gdsc = { + .name = "ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_2_gdsc = { +@@ -1748,6 +1754,7 @@ static struct gdsc ife_2_gdsc = { + .name = "ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc titan_top_gdsc = { +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch b/queue-6.17/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..7ee9a65080 --- /dev/null +++ b/queue-6.17/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch @@ -0,0 +1,50 @@ +From 63af900a43ab4df98a7032e41ffc6cfb9e9a5bfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:55 +0200 +Subject: clk: qcom: camcc-sm7150: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit 415aad75c7e5cdb72e0672dc1159be1a99535ecd ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly. + +Fixes: 9f0532da4226 ("clk: qcom: Add Camera Clock Controller driver for SM7150") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-2-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm7150.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c +index 4a3baf5d8e858..590548cac45bf 100644 +--- a/drivers/clk/qcom/camcc-sm7150.c ++++ b/drivers/clk/qcom/camcc-sm7150.c +@@ -139,13 +139,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = { + /* 1920MHz configuration */ + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .early_output_mask = BIT(3), +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), + .config_ctl_hi_val = 0x400003d6, + .config_ctl_val = 0x20000954, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch b/queue-6.17/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..a1a355b741 --- /dev/null +++ b/queue-6.17/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,113 @@ +From ad48ff7054dbfc0c4f12a4605d6a9d37903b6605 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:45 +0300 +Subject: clk: qcom: camcc-sm8550: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit d8f1121ebf4036884fc9ab1968f606523dd1c1fe ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM8550 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: ccc4e6a061a2 ("clk: qcom: camcc-sm8550: Add camera clock controller driver for SM8550") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-2-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm8550.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c +index 63aed9e4c362d..b8ece8a57a8a9 100644 +--- a/drivers/clk/qcom/camcc-sm8550.c ++++ b/drivers/clk/qcom/camcc-sm8550.c +@@ -3204,6 +3204,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { + }, + }; + ++static struct gdsc cam_cc_titan_top_gdsc; ++ + static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, +@@ -3213,6 +3215,7 @@ static struct gdsc cam_cc_bps_gdsc = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3225,6 +3228,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3237,6 +3241,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3249,6 +3254,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { + .name = "cam_cc_ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3261,6 +3267,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3273,6 +3280,7 @@ static struct gdsc cam_cc_sbi_gdsc = { + .name = "cam_cc_sbi_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3285,6 +3293,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { + .name = "cam_cc_sfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3297,6 +3306,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = { + .name = "cam_cc_sfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch b/queue-6.17/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch new file mode 100644 index 0000000000..a220fabc62 --- /dev/null +++ b/queue-6.17/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch @@ -0,0 +1,46 @@ +From 1c3539cca3126679a4452134da0a9a1f155c48a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:35:26 +0800 +Subject: clk: qcom: gcc-ipq5424: Correct the icc_first_node_id + +From: Luo Jie + +[ Upstream commit 464ce94531f5a62ce29081a9d3c70eb4d525f443 ] + +Update to use the expected icc_first_node_id for registering the icc +clocks, ensuring correct association of clocks with interconnect nodes. + +Fixes: 170f3d2c065e ("clk: qcom: ipq5424: Use icc-clk for enabling NoC related clocks") +Reviewed-by: Konrad Dybcio +Signed-off-by: Luo Jie +Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-1-081f4956be02@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq5424.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c +index 3d42f3d85c7a9..71afa1b86b723 100644 +--- a/drivers/clk/qcom/gcc-ipq5424.c ++++ b/drivers/clk/qcom/gcc-ipq5424.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3284,6 +3284,7 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = { + .num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws), + .icc_hws = icc_ipq5424_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws), ++ .icc_first_node_id = IPQ_APPS_ID, + }; + + static int gcc_ipq5424_probe(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch b/queue-6.17/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch new file mode 100644 index 0000000000..1f51762c07 --- /dev/null +++ b/queue-6.17/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch @@ -0,0 +1,62 @@ +From b4acd93699688c143b47a4b21bf3cf7348dca50e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 15:07:54 +0530 +Subject: clk: qcom: gcc-qcs615: Update the SDCC clock to use shared_floor_ops + +From: Taniya Das + +[ Upstream commit 0820c9373369c83de5202871d02682d583a91a9c ] + +Fix "gcc_sdcc2_apps_clk_src: rcg didn't update its configuration" during +boot. This happens due to the floor_ops tries to update the rcg +configuration even if the clock is not enabled. +The shared_floor_ops ensures that the RCG is safely parked and the new +parent configuration is cached in the parked_cfg when the clock is off. + +Ensure to use the ops for the other SDCC clock instances as well. + +Fixes: 39d6dcf67fe9 ("clk: qcom: gcc: Add support for QCS615 GCC clocks") +Reviewed-by: Abel Vesa +Signed-off-by: Taniya Das +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029-sdcc_rcg2_shared_ops-v3-1-ecf47d9601d1@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-qcs615.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c +index 9695446bc2a3c..5b3b8dd4f114b 100644 +--- a/drivers/clk/qcom/gcc-qcs615.c ++++ b/drivers/clk/qcom/gcc-qcs615.c +@@ -784,7 +784,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +@@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +@@ -830,7 +830,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch b/queue-6.17/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch new file mode 100644 index 0000000000..2dd8ef0adb --- /dev/null +++ b/queue-6.17/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch @@ -0,0 +1,37 @@ +From 63cffec5e22c78442266f9bc5b9a27ce32491538 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 00:08:30 +0530 +Subject: clk: qcom: gcc-sm8750: Add a new frequency for sdcc2 clock + +From: Taniya Das + +[ Upstream commit 393f7834cd2b1eaf4a9eff2701e706e73e660dd7 ] + +The SD card support requires a 37.5MHz clock; add it to the frequency +list for the storage SW driver to be able to request for the frequency. + +Fixes: 3267c774f3ff ("clk: qcom: Add support for GCC on SM8750") +Signed-off-by: Taniya Das +Reviewed-by: Imran Shaik +Link: https://lore.kernel.org/r/20250924-sm8750_gcc_sdcc2_frequency-v1-1-541fd321125f@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8750.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c +index 8092dd6b37b56..def86b71a3da5 100644 +--- a/drivers/clk/qcom/gcc-sm8750.c ++++ b/drivers/clk/qcom/gcc-sm8750.c +@@ -1012,6 +1012,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { + static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), ++ F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch b/queue-6.17/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch new file mode 100644 index 0000000000..4fcc478273 --- /dev/null +++ b/queue-6.17/clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch @@ -0,0 +1,1100 @@ +From 561fccbd520fa63b478f029c00125fe873749054 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:14:39 +0200 +Subject: clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets + +From: Konrad Dybcio + +[ Upstream commit 8abe970efea56f44773713cf91032cd2fd4d8c01 ] + +Currently, some of the USB4 clocks/resets are described, but not all +of the back-end muxes are present. Configuring them properly is +necessary for proper operation of the hardware. + +Add all the resets & muxes and wire up any unaccounted USB4 clock paths. + +Fixes: 161b7c401f4b ("clk: qcom: Add Global Clock controller (GCC) driver for X1E80100") +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Konrad Dybcio +Reviewed-by: Taniya Das +Reviewed-by: Abel Vesa +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251003-topic-hamoa_gcc_usb4-v2-2-61d27a14ee65@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-x1e80100.c | 698 +++++++++++++++++++++++++++++++- + 1 file changed, 681 insertions(+), 17 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-x1e80100.c b/drivers/clk/qcom/gcc-x1e80100.c +index 301fc9fc32d8e..8804ad5d70be0 100644 +--- a/drivers/clk/qcom/gcc-x1e80100.c ++++ b/drivers/clk/qcom/gcc-x1e80100.c +@@ -32,6 +32,33 @@ enum { + DT_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE, + DT_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE, + DT_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE, ++ DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, ++ DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, ++ DT_QUSB4PHY_0_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_0_GCC_USB4_RX1_CLK, ++ DT_QUSB4PHY_1_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_1_GCC_USB4_RX1_CLK, ++ DT_QUSB4PHY_2_GCC_USB4_RX0_CLK, ++ DT_QUSB4PHY_2_GCC_USB4_RX1_CLK, ++ DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + }; + + enum { +@@ -42,10 +69,40 @@ enum { + P_GCC_GPLL7_OUT_MAIN, + P_GCC_GPLL8_OUT_MAIN, + P_GCC_GPLL9_OUT_MAIN, ++ P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, ++ P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, ++ P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, ++ P_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, ++ P_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC, ++ P_QUSB4PHY_0_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_0_GCC_USB4_RX1_CLK, ++ P_QUSB4PHY_1_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_1_GCC_USB4_RX1_CLK, ++ P_QUSB4PHY_2_GCC_USB4_RX0_CLK, ++ P_QUSB4PHY_2_GCC_USB4_RX1_CLK, + P_SLEEP_CLK, + P_USB3_PHY_0_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_1_WRAPPER_GCC_USB30_PIPE_CLK, + P_USB3_PHY_2_WRAPPER_GCC_USB30_PIPE_CLK, ++ P_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ P_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, ++ P_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK, ++ P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, + }; + + static struct clk_alpha_pll gcc_gpll0 = { +@@ -320,6 +377,342 @@ static const struct freq_tbl ftbl_gcc_gp1_clk_src[] = { + { } + }; + ++static const struct clk_parent_data gcc_parent_data_13[] = { ++ { .index = DT_GCC_USB4_0_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_14[] = { ++ { .index = DT_GCC_USB4_0_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_15[] = { ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_16[] = { ++ { .index = DT_GCC_USB4_0_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_17[] = { ++ { .index = DT_QUSB4PHY_0_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_18[] = { ++ { .index = DT_QUSB4PHY_0_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_19[] = { ++ { .index = DT_GCC_USB4_0_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_0_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_20[] = { ++ { .index = DT_GCC_USB4_1_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_21[] = { ++ { .index = DT_GCC_USB4_1_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_22[] = { ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_23[] = { ++ { .index = DT_GCC_USB4_1_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_24[] = { ++ { .index = DT_QUSB4PHY_1_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_25[] = { ++ { .index = DT_QUSB4PHY_1_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_26[] = { ++ { .index = DT_GCC_USB4_1_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_1_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_27[] = { ++ { .index = DT_GCC_USB4_2_PHY_DP0_GMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_28[] = { ++ { .index = DT_GCC_USB4_2_PHY_DP1_GMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_29[] = { ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_30[] = { ++ { .index = DT_GCC_USB4_2_PHY_PCIE_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_31[] = { ++ { .index = DT_QUSB4PHY_2_GCC_USB4_RX0_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_32[] = { ++ { .index = DT_QUSB4PHY_2_GCC_USB4_RX1_CLK }, ++ { .index = DT_BI_TCXO }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_33[] = { ++ { .index = DT_GCC_USB4_2_PHY_SYS_PIPEGMUX_CLK_SRC }, ++ { .index = DT_USB4_2_PHY_GCC_USB4_PCIE_PIPE_CLK }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp0_clk_src = { ++ .reg = 0x9f06c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_13, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_dp1_clk_src = { ++ .reg = 0x9f114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_14, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x9f0d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_15, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x9f104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_16, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx0_clk_src = { ++ .reg = 0x9f0ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_17, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_rx1_clk_src = { ++ .reg = 0x9f0bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_18, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_0_phy_sys_clk_src = { ++ .reg = 0x9f0e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_0_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_19, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp0_clk_src = { ++ .reg = 0x2b06c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_20, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_dp1_clk_src = { ++ .reg = 0x2b114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_21, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x2b0d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_22, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x2b104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_23, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx0_clk_src = { ++ .reg = 0x2b0ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_24, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_rx1_clk_src = { ++ .reg = 0x2b0bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_25, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_1_phy_sys_clk_src = { ++ .reg = 0x2b0e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_1_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_26, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp0_clk_src = { ++ .reg = 0x1106c, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_dp0_clk_src", ++ .parent_data = gcc_parent_data_27, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_dp1_clk_src = { ++ .reg = 0x11114, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_dp1_clk_src", ++ .parent_data = gcc_parent_data_28, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_p2rr2p_pipe_clk_src = { ++ .reg = 0x110d4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk_src", ++ .parent_data = gcc_parent_data_29, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_pcie_pipe_mux_clk_src = { ++ .reg = 0x11104, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_pcie_pipe_mux_clk_src", ++ .parent_data = gcc_parent_data_30, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx0_clk_src = { ++ .reg = 0x110ac, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_rx0_clk_src", ++ .parent_data = gcc_parent_data_31, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_rx1_clk_src = { ++ .reg = 0x110bc, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_rx1_clk_src", ++ .parent_data = gcc_parent_data_32, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ ++static struct clk_regmap_phy_mux gcc_usb4_2_phy_sys_clk_src = { ++ .reg = 0x110e4, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb4_2_phy_sys_clk_src", ++ .parent_data = gcc_parent_data_33, ++ .ops = &clk_regmap_phy_mux_ops, ++ }, ++ }, ++}; ++ + static struct clk_rcg2 gcc_gp1_clk_src = { + .cmd_rcgr = 0x64004, + .mnd_width = 16, +@@ -2790,6 +3183,11 @@ static struct clk_branch gcc_pcie_0_pipe_clk = { + .enable_mask = BIT(25), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_0_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2879,6 +3277,11 @@ static struct clk_branch gcc_pcie_1_pipe_clk = { + .enable_mask = BIT(30), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_1_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2968,6 +3371,11 @@ static struct clk_branch gcc_pcie_2_pipe_clk = { + .enable_mask = BIT(23), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_pcie_2_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5156,6 +5564,33 @@ static struct clk_regmap_mux gcc_usb3_prim_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_34[] = { ++ { P_GCC_USB3_PRIM_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_34[] = { ++ { .hw = &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_0_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_0_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_prim_phy_pipe_clk_src = { ++ .reg = 0x39070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_34, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_prim_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_34, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_34), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x39068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5167,7 +5602,7 @@ static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_prim_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_prim_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5227,6 +5662,33 @@ static struct clk_regmap_mux gcc_usb3_sec_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_35[] = { ++ { P_GCC_USB3_SEC_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_35[] = { ++ { .hw = &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_1_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_1_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_sec_phy_pipe_clk_src = { ++ .reg = 0xa1070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_35, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_sec_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_35, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_35), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0xa1068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5238,7 +5700,7 @@ static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_sec_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_sec_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5298,6 +5760,33 @@ static struct clk_regmap_mux gcc_usb3_tert_phy_pipe_clk_src = { + }, + }; + ++static const struct parent_map gcc_parent_map_36[] = { ++ { P_GCC_USB3_TERT_PHY_PIPE_CLK_SRC, 0 }, ++ { P_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK, 1 }, ++ { P_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC, 3 }, ++}; ++ ++static const struct clk_parent_data gcc_parent_data_36[] = { ++ { .hw = &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw }, ++ { .index = DT_USB4_2_PHY_GCC_USB4RTR_MAX_PIPE_CLK }, ++ { .index = DT_GCC_USB4_2_PHY_PIPEGMUX_CLK_SRC }, ++}; ++ ++static struct clk_regmap_mux gcc_usb34_tert_phy_pipe_clk_src = { ++ .reg = 0xa2070, ++ .shift = 0, ++ .width = 2, ++ .parent_map = gcc_parent_map_36, ++ .clkr = { ++ .hw.init = &(const struct clk_init_data) { ++ .name = "gcc_usb34_tert_phy_pipe_clk_src", ++ .parent_data = gcc_parent_data_36, ++ .num_parents = ARRAY_SIZE(gcc_parent_data_36), ++ .ops = &clk_regmap_mux_closest_ops, ++ }, ++ }, ++}; ++ + static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .halt_reg = 0xa2068, + .halt_check = BRANCH_HALT_SKIP, +@@ -5309,7 +5798,7 @@ static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb3_tert_phy_pipe_clk", + .parent_hws = (const struct clk_hw*[]) { +- &gcc_usb3_tert_phy_pipe_clk_src.clkr.hw, ++ &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, +@@ -5335,12 +5824,17 @@ static struct clk_branch gcc_usb4_0_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_0_dp0_clk = { + .halt_reg = 0x9f060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5348,12 +5842,17 @@ static struct clk_branch gcc_usb4_0_dp0_clk = { + + static struct clk_branch gcc_usb4_0_dp1_clk = { + .halt_reg = 0x9f108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5385,6 +5884,11 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5398,6 +5902,11 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + .enable_mask = BIT(19), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5405,12 +5914,17 @@ static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_0_phy_rx0_clk = { + .halt_reg = 0x9f0b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f0b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5418,12 +5932,17 @@ static struct clk_branch gcc_usb4_0_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_0_phy_rx1_clk = { + .halt_reg = 0x9f0c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x9f0c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5439,6 +5958,11 @@ static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_prim_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5470,6 +5994,11 @@ static struct clk_branch gcc_usb4_0_sys_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_0_sys_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_0_phy_sys_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5512,12 +6041,17 @@ static struct clk_branch gcc_usb4_1_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_1_dp0_clk = { + .halt_reg = 0x2b060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5525,12 +6059,17 @@ static struct clk_branch gcc_usb4_1_dp0_clk = { + + static struct clk_branch gcc_usb4_1_dp1_clk = { + .halt_reg = 0x2b108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5562,6 +6101,11 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5575,6 +6119,11 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5582,12 +6131,17 @@ static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_1_phy_rx0_clk = { + .halt_reg = 0x2b0b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b0b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5595,12 +6149,17 @@ static struct clk_branch gcc_usb4_1_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_1_phy_rx1_clk = { + .halt_reg = 0x2b0c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b0c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5616,6 +6175,11 @@ static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_sec_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5647,6 +6211,11 @@ static struct clk_branch gcc_usb4_1_sys_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_1_sys_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_1_phy_sys_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5689,12 +6258,17 @@ static struct clk_branch gcc_usb4_2_cfg_ahb_clk = { + + static struct clk_branch gcc_usb4_2_dp0_clk = { + .halt_reg = 0x11060, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x11060, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_dp0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5702,12 +6276,17 @@ static struct clk_branch gcc_usb4_2_dp0_clk = { + + static struct clk_branch gcc_usb4_2_dp1_clk = { + .halt_reg = 0x11108, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x11108, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_dp1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_dp1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5739,6 +6318,11 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_p2rr2p_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5752,6 +6336,11 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + .enable_mask = BIT(1), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_pcie_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5759,12 +6348,17 @@ static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + + static struct clk_branch gcc_usb4_2_phy_rx0_clk = { + .halt_reg = 0x110b0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x110b0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx0_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_rx0_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5772,12 +6366,17 @@ static struct clk_branch gcc_usb4_2_phy_rx0_clk = { + + static struct clk_branch gcc_usb4_2_phy_rx1_clk = { + .halt_reg = 0x110c0, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x110c0, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_rx1_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb4_2_phy_rx1_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -5793,6 +6392,11 @@ static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "gcc_usb4_2_phy_usb_pipe_clk", ++ .parent_hws = (const struct clk_hw*[]) { ++ &gcc_usb34_tert_phy_pipe_clk_src.clkr.hw, ++ }, ++ .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -6483,6 +7087,9 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB30_TERT_MOCK_UTMI_CLK_SRC] = &gcc_usb30_tert_mock_utmi_clk_src.clkr, + [GCC_USB30_TERT_MOCK_UTMI_POSTDIV_CLK_SRC] = &gcc_usb30_tert_mock_utmi_postdiv_clk_src.clkr, + [GCC_USB30_TERT_SLEEP_CLK] = &gcc_usb30_tert_sleep_clk.clkr, ++ [GCC_USB34_PRIM_PHY_PIPE_CLK_SRC] = &gcc_usb34_prim_phy_pipe_clk_src.clkr, ++ [GCC_USB34_SEC_PHY_PIPE_CLK_SRC] = &gcc_usb34_sec_phy_pipe_clk_src.clkr, ++ [GCC_USB34_TERT_PHY_PIPE_CLK_SRC] = &gcc_usb34_tert_phy_pipe_clk_src.clkr, + [GCC_USB3_MP_PHY_AUX_CLK] = &gcc_usb3_mp_phy_aux_clk.clkr, + [GCC_USB3_MP_PHY_AUX_CLK_SRC] = &gcc_usb3_mp_phy_aux_clk_src.clkr, + [GCC_USB3_MP_PHY_COM_AUX_CLK] = &gcc_usb3_mp_phy_com_aux_clk.clkr, +@@ -6508,11 +7115,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_0_DP1_CLK] = &gcc_usb4_0_dp1_clk.clkr, + [GCC_USB4_0_MASTER_CLK] = &gcc_usb4_0_master_clk.clkr, + [GCC_USB4_0_MASTER_CLK_SRC] = &gcc_usb4_0_master_clk_src.clkr, ++ [GCC_USB4_0_PHY_DP0_CLK_SRC] = &gcc_usb4_0_phy_dp0_clk_src.clkr, ++ [GCC_USB4_0_PHY_DP1_CLK_SRC] = &gcc_usb4_0_phy_dp1_clk_src.clkr, + [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_0_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_0_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK] = &gcc_usb4_0_phy_pcie_pipe_clk.clkr, + [GCC_USB4_0_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_0_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_0_PHY_RX0_CLK] = &gcc_usb4_0_phy_rx0_clk.clkr, ++ [GCC_USB4_0_PHY_RX0_CLK_SRC] = &gcc_usb4_0_phy_rx0_clk_src.clkr, + [GCC_USB4_0_PHY_RX1_CLK] = &gcc_usb4_0_phy_rx1_clk.clkr, ++ [GCC_USB4_0_PHY_RX1_CLK_SRC] = &gcc_usb4_0_phy_rx1_clk_src.clkr, ++ [GCC_USB4_0_PHY_SYS_CLK_SRC] = &gcc_usb4_0_phy_sys_clk_src.clkr, + [GCC_USB4_0_PHY_USB_PIPE_CLK] = &gcc_usb4_0_phy_usb_pipe_clk.clkr, + [GCC_USB4_0_SB_IF_CLK] = &gcc_usb4_0_sb_if_clk.clkr, + [GCC_USB4_0_SB_IF_CLK_SRC] = &gcc_usb4_0_sb_if_clk_src.clkr, +@@ -6524,11 +7138,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_1_DP1_CLK] = &gcc_usb4_1_dp1_clk.clkr, + [GCC_USB4_1_MASTER_CLK] = &gcc_usb4_1_master_clk.clkr, + [GCC_USB4_1_MASTER_CLK_SRC] = &gcc_usb4_1_master_clk_src.clkr, ++ [GCC_USB4_1_PHY_DP0_CLK_SRC] = &gcc_usb4_1_phy_dp0_clk_src.clkr, ++ [GCC_USB4_1_PHY_DP1_CLK_SRC] = &gcc_usb4_1_phy_dp1_clk_src.clkr, + [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_1_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_1_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK] = &gcc_usb4_1_phy_pcie_pipe_clk.clkr, + [GCC_USB4_1_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_1_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_1_PHY_RX0_CLK] = &gcc_usb4_1_phy_rx0_clk.clkr, ++ [GCC_USB4_1_PHY_RX0_CLK_SRC] = &gcc_usb4_1_phy_rx0_clk_src.clkr, + [GCC_USB4_1_PHY_RX1_CLK] = &gcc_usb4_1_phy_rx1_clk.clkr, ++ [GCC_USB4_1_PHY_RX1_CLK_SRC] = &gcc_usb4_1_phy_rx1_clk_src.clkr, ++ [GCC_USB4_1_PHY_SYS_CLK_SRC] = &gcc_usb4_1_phy_sys_clk_src.clkr, + [GCC_USB4_1_PHY_USB_PIPE_CLK] = &gcc_usb4_1_phy_usb_pipe_clk.clkr, + [GCC_USB4_1_SB_IF_CLK] = &gcc_usb4_1_sb_if_clk.clkr, + [GCC_USB4_1_SB_IF_CLK_SRC] = &gcc_usb4_1_sb_if_clk_src.clkr, +@@ -6540,11 +7161,18 @@ static struct clk_regmap *gcc_x1e80100_clocks[] = { + [GCC_USB4_2_DP1_CLK] = &gcc_usb4_2_dp1_clk.clkr, + [GCC_USB4_2_MASTER_CLK] = &gcc_usb4_2_master_clk.clkr, + [GCC_USB4_2_MASTER_CLK_SRC] = &gcc_usb4_2_master_clk_src.clkr, ++ [GCC_USB4_2_PHY_DP0_CLK_SRC] = &gcc_usb4_2_phy_dp0_clk_src.clkr, ++ [GCC_USB4_2_PHY_DP1_CLK_SRC] = &gcc_usb4_2_phy_dp1_clk_src.clkr, + [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK] = &gcc_usb4_2_phy_p2rr2p_pipe_clk.clkr, ++ [GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC] = &gcc_usb4_2_phy_p2rr2p_pipe_clk_src.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK] = &gcc_usb4_2_phy_pcie_pipe_clk.clkr, + [GCC_USB4_2_PHY_PCIE_PIPE_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_clk_src.clkr, ++ [GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC] = &gcc_usb4_2_phy_pcie_pipe_mux_clk_src.clkr, + [GCC_USB4_2_PHY_RX0_CLK] = &gcc_usb4_2_phy_rx0_clk.clkr, ++ [GCC_USB4_2_PHY_RX0_CLK_SRC] = &gcc_usb4_2_phy_rx0_clk_src.clkr, + [GCC_USB4_2_PHY_RX1_CLK] = &gcc_usb4_2_phy_rx1_clk.clkr, ++ [GCC_USB4_2_PHY_RX1_CLK_SRC] = &gcc_usb4_2_phy_rx1_clk_src.clkr, ++ [GCC_USB4_2_PHY_SYS_CLK_SRC] = &gcc_usb4_2_phy_sys_clk_src.clkr, + [GCC_USB4_2_PHY_USB_PIPE_CLK] = &gcc_usb4_2_phy_usb_pipe_clk.clkr, + [GCC_USB4_2_SB_IF_CLK] = &gcc_usb4_2_sb_if_clk.clkr, + [GCC_USB4_2_SB_IF_CLK_SRC] = &gcc_usb4_2_sb_if_clk_src.clkr, +@@ -6660,16 +7288,52 @@ static const struct qcom_reset_map gcc_x1e80100_resets[] = { + [GCC_USB3_UNIPHY_MP0_BCR] = { 0x19000 }, + [GCC_USB3_UNIPHY_MP1_BCR] = { 0x54000 }, + [GCC_USB3PHY_PHY_PRIM_BCR] = { 0x50004 }, ++ [GCC_USB4PHY_PHY_PRIM_BCR] = { 0x5000c }, + [GCC_USB3PHY_PHY_SEC_BCR] = { 0x2a004 }, ++ [GCC_USB4PHY_PHY_SEC_BCR] = { 0x2a00c }, + [GCC_USB3PHY_PHY_TERT_BCR] = { 0xa3004 }, ++ [GCC_USB4PHY_PHY_TERT_BCR] = { 0xa300c }, + [GCC_USB3UNIPHY_PHY_MP0_BCR] = { 0x19004 }, + [GCC_USB3UNIPHY_PHY_MP1_BCR] = { 0x54004 }, + [GCC_USB4_0_BCR] = { 0x9f000 }, + [GCC_USB4_0_DP0_PHY_PRIM_BCR] = { 0x50010 }, +- [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, +- [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, ++ [GCC_USB4_0_MISC_USB4_SYS_BCR] = { .reg = 0xad0f8, .bit = 0 }, ++ [GCC_USB4_0_MISC_RX_CLK_0_BCR] = { .reg = 0xad0f8, .bit = 1 }, ++ [GCC_USB4_0_MISC_RX_CLK_1_BCR] = { .reg = 0xad0f8, .bit = 2 }, ++ [GCC_USB4_0_MISC_USB_PIPE_BCR] = { .reg = 0xad0f8, .bit = 3 }, ++ [GCC_USB4_0_MISC_PCIE_PIPE_BCR] = { .reg = 0xad0f8, .bit = 4 }, ++ [GCC_USB4_0_MISC_TMU_BCR] = { .reg = 0xad0f8, .bit = 5 }, ++ [GCC_USB4_0_MISC_SB_IF_BCR] = { .reg = 0xad0f8, .bit = 6 }, ++ [GCC_USB4_0_MISC_HIA_MSTR_BCR] = { .reg = 0xad0f8, .bit = 7 }, ++ [GCC_USB4_0_MISC_AHB_BCR] = { .reg = 0xad0f8, .bit = 8 }, ++ [GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 9 }, ++ [GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xad0f8, .bit = 10 }, + [GCC_USB4_1_BCR] = { 0x2b000 }, ++ [GCC_USB4_1_DP0_PHY_SEC_BCR] = { 0x2a010 }, ++ [GCC_USB4_1_MISC_USB4_SYS_BCR] = { .reg = 0xae0f8, .bit = 0 }, ++ [GCC_USB4_1_MISC_RX_CLK_0_BCR] = { .reg = 0xae0f8, .bit = 1 }, ++ [GCC_USB4_1_MISC_RX_CLK_1_BCR] = { .reg = 0xae0f8, .bit = 2 }, ++ [GCC_USB4_1_MISC_USB_PIPE_BCR] = { .reg = 0xae0f8, .bit = 3 }, ++ [GCC_USB4_1_MISC_PCIE_PIPE_BCR] = { .reg = 0xae0f8, .bit = 4 }, ++ [GCC_USB4_1_MISC_TMU_BCR] = { .reg = 0xae0f8, .bit = 5 }, ++ [GCC_USB4_1_MISC_SB_IF_BCR] = { .reg = 0xae0f8, .bit = 6 }, ++ [GCC_USB4_1_MISC_HIA_MSTR_BCR] = { .reg = 0xae0f8, .bit = 7 }, ++ [GCC_USB4_1_MISC_AHB_BCR] = { .reg = 0xae0f8, .bit = 8 }, ++ [GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 9 }, ++ [GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xae0f8, .bit = 10 }, + [GCC_USB4_2_BCR] = { 0x11000 }, ++ [GCC_USB4_2_DP0_PHY_TERT_BCR] = { 0xa3010 }, ++ [GCC_USB4_2_MISC_USB4_SYS_BCR] = { .reg = 0xaf0f8, .bit = 0 }, ++ [GCC_USB4_2_MISC_RX_CLK_0_BCR] = { .reg = 0xaf0f8, .bit = 1 }, ++ [GCC_USB4_2_MISC_RX_CLK_1_BCR] = { .reg = 0xaf0f8, .bit = 2 }, ++ [GCC_USB4_2_MISC_USB_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 3 }, ++ [GCC_USB4_2_MISC_PCIE_PIPE_BCR] = { .reg = 0xaf0f8, .bit = 4 }, ++ [GCC_USB4_2_MISC_TMU_BCR] = { .reg = 0xaf0f8, .bit = 5 }, ++ [GCC_USB4_2_MISC_SB_IF_BCR] = { .reg = 0xaf0f8, .bit = 6 }, ++ [GCC_USB4_2_MISC_HIA_MSTR_BCR] = { .reg = 0xaf0f8, .bit = 7 }, ++ [GCC_USB4_2_MISC_AHB_BCR] = { .reg = 0xaf0f8, .bit = 8 }, ++ [GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 9 }, ++ [GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR] = { .reg = 0xaf0f8, .bit = 10 }, + [GCC_USB_0_PHY_BCR] = { 0x50020 }, + [GCC_USB_1_PHY_BCR] = { 0x2a020 }, + [GCC_USB_2_PHY_BCR] = { 0xa3020 }, +-- +2.51.0 + diff --git a/queue-6.17/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch b/queue-6.17/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch new file mode 100644 index 0000000000..4398f7d501 --- /dev/null +++ b/queue-6.17/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch @@ -0,0 +1,39 @@ +From 40b1ffad0e854a9b454d761c26c059864f7273c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jun 2025 21:37:58 +0200 +Subject: clk: qcom: rpmh: Define RPMH_IPA_CLK on QCS615 + +From: Konrad Dybcio + +[ Upstream commit 17e4db05930e455770b15b77708a07681ed24efc ] + +This was previously (mis)represented in the interconnect driver, move +the resource under the clk-rpmh driver control, just like we did for +all platforms in the past, see e.g. Commit aa055bf158cd ("clk: qcom: +rpmh: define IPA clocks where required") + +Fixes: 42a1905a10d6 ("clk: qcom: rpmhcc: Add support for QCS615 Clocks") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250627-topic-qcs615_icc_ipa-v1-4-dc47596cde69@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-rpmh.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c +index 1496fb3de4be8..8aad1676d8da8 100644 +--- a/drivers/clk/qcom/clk-rpmh.c ++++ b/drivers/clk/qcom/clk-rpmh.c +@@ -850,6 +850,7 @@ static struct clk_hw *qcs615_rpmh_clocks[] = { + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, ++ [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, + }; + + static const struct clk_rpmh_desc clk_rpmh_qcs615 = { +-- +2.51.0 + diff --git a/queue-6.17/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch b/queue-6.17/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch new file mode 100644 index 0000000000..311d9feb9d --- /dev/null +++ b/queue-6.17/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch @@ -0,0 +1,58 @@ +From 91319d6a37e5250b78a80515488f6ece5769e712 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 05:04:43 +0200 +Subject: clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle + callback + +From: Marek Vasut + +[ Upstream commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab ] + +R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page +583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) +indicate after reset has been asserted by writing a matching reset bit +into register SRCR, it is mandatory to wait 1ms. + +This 1ms delay is documented on R-Car V4H and V4M, it is currently +unclear whether S4 is affected as well. This patch does apply the extra +delay on R-Car S4 as well. + +Fix the reset driver to respect the additional delay when toggling +resets. Drivers which use separate reset_control_(de)assert() must +assure matching delay in their driver code. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index de1cf7ba45b78..7063d896249ea 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -689,8 +689,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + /* Reset module */ + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); ++ /* ++ * On R-Car Gen4, delay after SRCR has been written is 1ms. ++ * On older SoCs, delay after SRCR has been written is 35us ++ * (one cycle of the RCLK clock @ ca. 32 kHz). ++ */ ++ if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) ++ usleep_range(1000, 2000); ++ else ++ usleep_range(35, 1000); + + /* Release module from reset state */ + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +-- +2.51.0 + diff --git a/queue-6.17/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch b/queue-6.17/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch new file mode 100644 index 0000000000..fe011b6fce --- /dev/null +++ b/queue-6.17/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch @@ -0,0 +1,124 @@ +From 2d2f1d03604cd70435a98d231ea164fc421404b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 18:20:38 +0200 +Subject: clk: renesas: cpg-mssr: Read back reset registers to assure values + latched + +From: Marek Vasut + +[ Upstream commit b91401af6c00ffab003698bfabd4c166df30748b ] + +On R-Car V4H, the PCIEC controller DBI read would generate an SError in +case the controller reset is released by writing SRSTCLR register first, +and immediately afterward reading some PCIEC controller DBI register. +The issue triggers in rcar_gen4_pcie_additional_common_init() on +dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first +read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). + +The reset controller which contains the SRSTCLR register and the PCIEC +controller which contains the DBI register share the same root access +bus, but the bus then splits into separate segments before reaching each +IP. Even if the SRSTCLR write access was posted on the bus before the +DBI read access, it seems the DBI read access may reach the PCIEC +controller before the SRSTCLR write completed, and trigger the SError. + +Mitigate the issue by adding a dummy SRSTCLR read, which assures the +SRSTCLR write completes fully and is latched into the reset controller, +before the PCIEC DBI read access can occur. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Reviewed-by: Wolfram Sang +Tested-by: Geert Uytterhoeven +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 7063d896249ea..a0a68ec0490f7 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -676,18 +676,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, + + #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) + +-static int cpg_mssr_reset(struct reset_controller_dev *rcdev, +- unsigned long id) ++static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, ++ const char *func, bool set, unsigned long id) + { + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + unsigned int reg = id / 32; + unsigned int bit = id % 32; ++ const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; + u32 bitmask = BIT(bit); + +- dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); ++ if (func) ++ dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); ++ ++ writel(bitmask, priv->pub.base0 + off); ++ readl(priv->pub.base0 + off); ++ barrier_data(priv->pub.base0 + off); ++ ++ return 0; ++} ++ ++static int cpg_mssr_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + + /* Reset module */ +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); ++ cpg_mssr_reset_operate(rcdev, "reset", true, id); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -700,36 +714,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- +- return 0; ++ return cpg_mssr_reset_operate(rcdev, NULL, false, id); + } + + static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "assert", true, id); + } + + static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "deassert", false, id); + } + + static int cpg_mssr_status(struct reset_controller_dev *rcdev, +-- +2.51.0 + diff --git a/queue-6.17/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-6.17/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..00b96a1254 --- /dev/null +++ b/queue-6.17/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 2aaf4439f42f146459912b11f7b01b4af6e157f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index dcda19318b2a9..0f5c91b5dfa99 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -1333,9 +1333,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-6.17/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch b/queue-6.17/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch new file mode 100644 index 0000000000..f750e4c61f --- /dev/null +++ b/queue-6.17/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch @@ -0,0 +1,49 @@ +From 9238c3bb40902c21669cd377d16fd73d59e05877 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 16:51:23 +0000 +Subject: clk: renesas: r9a09g077: Propagate rate changes to parent clocks + +From: Lad Prabhakar + +[ Upstream commit 145dfd70b9c70e5bc03494a7ce8fa3748ac01af3 ] + +Add the CLK_SET_RATE_PARENT flag to divider clock registration so that rate +changes can propagate to parent clocks when needed. This allows the CPG +divider clocks to request rate adjustments from their parent, ensuring +correct frequency scaling and improved flexibility in clock rate selection. + +Fixes: 065fe720eec6e ("clk: renesas: Add support for R9A09G077 SoC") +Signed-off-by: Lad Prabhakar +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251028165127.991351-2-prabhakar.mahadev-lad.rj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a09g077-cpg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c +index c920d6a9707f1..c8c28909ed9db 100644 +--- a/drivers/clk/renesas/r9a09g077-cpg.c ++++ b/drivers/clk/renesas/r9a09g077-cpg.c +@@ -178,7 +178,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, +- parent_name, 0, ++ parent_name, CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), +@@ -187,7 +187,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, + &pub->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, +- parent_name, 0, ++ parent_name, CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), +-- +2.51.0 + diff --git a/queue-6.17/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch b/queue-6.17/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch new file mode 100644 index 0000000000..fdf2c678da --- /dev/null +++ b/queue-6.17/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch @@ -0,0 +1,88 @@ +From 74260b83cc62eaaf73d413594a74bea57c69f54b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 14:03:29 -0500 +Subject: clk: spacemit: Set clk_hw_onecell_data::num before using flex array + +From: Charles Mirabile + +[ Upstream commit 23b2d2fb136959fd0a8e309c70be83d9b8841c7e ] + +When booting with KASAN enabled the following splat is +encountered during probe of the k1 clock driver: + +UBSAN: array-index-out-of-bounds in drivers/clk/spacemit/ccu-k1.c:1044:16 +index 0 is out of range for type 'clk_hw *[*]' +CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc5+ #1 PREEMPT(lazy) +Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10spacemit 10/01/2022 +Call Trace: +[] dump_backtrace+0x28/0x38 +[] show_stack+0x3a/0x50 +[] dump_stack_lvl+0x5a/0x80 +[] dump_stack+0x18/0x20 +[] ubsan_epilogue+0x10/0x48 +[] __ubsan_handle_out_of_bounds+0xa6/0xa8 +[] k1_ccu_probe+0x37e/0x420 +[] platform_probe+0x56/0x98 +[] really_probe+0x9e/0x350 +[] __driver_probe_device+0x80/0x138 +[] driver_probe_device+0x3a/0xd0 +[] __driver_attach+0xac/0x1b8 +[] bus_for_each_dev+0x6c/0xc8 +[] driver_attach+0x26/0x38 +[] bus_add_driver+0x13e/0x268 +[] driver_register+0x52/0x100 +[] __platform_driver_register+0x28/0x38 +[] k1_ccu_driver_init+0x22/0x38 +[] do_one_initcall+0x62/0x2a0 +[] do_initcalls+0x170/0x1a8 +[] kernel_init_freeable+0x16a/0x1e0 +[] kernel_init+0x2c/0x180 +[] ret_from_fork_kernel+0x16/0x1d8 +[] ret_from_fork_kernel_asm+0x16/0x18 +---[ end trace ]--- + +This is bogus and is simply a result of KASAN consulting the +`.num` member of the struct for bounds information (as it should +due to `__counted_by`) and finding 0 set by kzalloc() because it +has not been initialized before the loop that fills in the array. +The easy fix is to just move the line that sets `num` to before +the loop that fills the array so that KASAN has the information +it needs to accurately conclude that the access is valid. + +Fixes: 1b72c59db0add ("clk: spacemit: Add clock support for SpacemiT K1 SoC") +Tested-by: Yanko Kaneti +Signed-off-by: Charles Mirabile +Reviewed-by: Alex Elder +Reviewed-by: Troy Mitchell +Reviewed-by: Yixun Lan +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/spacemit/ccu-k1.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c +index 65e6de030717a..7c9585c9359de 100644 +--- a/drivers/clk/spacemit/ccu-k1.c ++++ b/drivers/clk/spacemit/ccu-k1.c +@@ -973,6 +973,8 @@ static int spacemit_ccu_register(struct device *dev, + if (!clk_data) + return -ENOMEM; + ++ clk_data->num = data->num; ++ + for (i = 0; i < data->num; i++) { + struct clk_hw *hw = data->hws[i]; + struct ccu_common *common; +@@ -999,8 +1001,6 @@ static int spacemit_ccu_register(struct device *dev, + clk_data->hws[i] = hw; + } + +- clk_data->num = data->num; +- + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); + if (ret) + dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); +-- +2.51.0 + diff --git a/queue-6.17/clocksource-drivers-nxp-stm-fix-section-mismatches.patch b/queue-6.17/clocksource-drivers-nxp-stm-fix-section-mismatches.patch new file mode 100644 index 0000000000..0bb4899743 --- /dev/null +++ b/queue-6.17/clocksource-drivers-nxp-stm-fix-section-mismatches.patch @@ -0,0 +1,94 @@ +From e07496cd08e5dcb8ec8e709fa19f7f71f01f61a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 07:49:43 +0200 +Subject: clocksource/drivers/nxp-stm: Fix section mismatches + +From: Johan Hovold + +[ Upstream commit b452d2c97eeccbf9c7ac5b3d2d9e80bf6d8a23db ] + +Platform drivers can be probed after their init sections have been +discarded (e.g. on probe deferral or manual rebind through sysfs) so the +probe function must not live in init. Device managed resource actions +similarly cannot be discarded. + +The "_probe" suffix of the driver structure name prevents modpost from +warning about this so replace it to catch any similar future issues. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Cc: stable@vger.kernel.org # 6.16 +Cc: Daniel Lezcano +Link: https://patch.msgid.link/20251017054943.7195-1-johan@kernel.org +Stable-dep-of: 6a2416892e89 ("clocksource/drivers/nxp-stm: Prevent driver unbind") +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index 8bca183abe8f2..bbb671b6e0284 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -177,15 +177,15 @@ static void nxp_stm_clocksource_resume(struct clocksource *cs) + nxp_stm_clocksource_enable(cs); + } + +-static void __init devm_clocksource_unregister(void *data) ++static void devm_clocksource_unregister(void *data) + { + struct stm_timer *stm_timer = data; + + clocksource_unregister(&stm_timer->cs); + } + +-static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer, +- const char *name, void __iomem *base, struct clk *clk) ++static int nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer, ++ const char *name, void __iomem *base, struct clk *clk) + { + int ret; + +@@ -295,9 +295,9 @@ static void nxp_stm_clockevent_resume(struct clock_event_device *ced) + nxp_stm_module_get(stm_timer); + } + +-static int __init nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer, +- const char *name, void __iomem *base, int irq, +- struct clk *clk, int cpu) ++static int nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer, ++ const char *name, void __iomem *base, int irq, ++ struct clk *clk, int cpu) + { + stm_timer->base = base; + stm_timer->rate = clk_get_rate(clk); +@@ -384,7 +384,7 @@ static irqreturn_t nxp_stm_module_interrupt(int irq, void *dev_id) + return IRQ_HANDLED; + } + +-static int __init nxp_stm_timer_probe(struct platform_device *pdev) ++static int nxp_stm_timer_probe(struct platform_device *pdev) + { + struct stm_timer *stm_timer; + struct device *dev = &pdev->dev; +@@ -480,14 +480,14 @@ static const struct of_device_id nxp_stm_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, nxp_stm_of_match); + +-static struct platform_driver nxp_stm_probe = { ++static struct platform_driver nxp_stm_driver = { + .probe = nxp_stm_timer_probe, + .driver = { + .name = "nxp-stm", + .of_match_table = nxp_stm_of_match, + }, + }; +-module_platform_driver(nxp_stm_probe); ++module_platform_driver(nxp_stm_driver); + + MODULE_DESCRIPTION("NXP System Timer Module driver"); + MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.17/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch b/queue-6.17/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch new file mode 100644 index 0000000000..e3fba55c52 --- /dev/null +++ b/queue-6.17/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch @@ -0,0 +1,45 @@ +From 0c88eb30d6f3fb37f8f9c83093ef4021c7200050 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 16:32:26 +0100 +Subject: clocksource/drivers/nxp-stm: Prevent driver unbind + +From: Johan Hovold + +[ Upstream commit 6a2416892e8942f5e2bfe9b85c0164f410a53a2d ] + +Clockevents cannot be deregistered so suppress the bind attributes to +prevent the driver from being unbound and releasing the underlying +resources after registration. + +Even if the driver can currently only be built-in, also switch to +builtin_platform_driver() to prevent it from being unloaded should +modular builds ever be enabled. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20251111153226.579-4-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index bbb671b6e0284..b0cd3bc7b096d 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -485,9 +485,10 @@ static struct platform_driver nxp_stm_driver = { + .driver = { + .name = "nxp-stm", + .of_match_table = nxp_stm_of_match, ++ .suppress_bind_attrs = true, + }, + }; +-module_platform_driver(nxp_stm_driver); ++builtin_platform_driver(nxp_stm_driver); + + MODULE_DESCRIPTION("NXP System Timer Module driver"); + MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.17/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch b/queue-6.17/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch new file mode 100644 index 0000000000..7317362b5f --- /dev/null +++ b/queue-6.17/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch @@ -0,0 +1,63 @@ +From 89262c7b82c02bbe015815a8d38bb88adf85990e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 17:07:10 +0800 +Subject: clocksource/drivers/ralink: Fix resource leaks in init error path + +From: Haotian Zhang + +[ Upstream commit 2ba8e2aae1324704565a7d4d66f199d056c9e3c6 ] + +The ralink_systick_init() function does not release all acquired resources +on its error paths. If irq_of_parse_and_map() or a subsequent call fails, +the previously created I/O memory mapping and IRQ mapping are leaked. + +Add goto-based error handling labels to ensure that all allocated +resources are correctly freed. + +Fixes: 1f2acc5a8a0a ("MIPS: ralink: Add support for systick timer found on newer ralink SoC") +Signed-off-by: Haotian Zhang +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20251030090710.1603-1-vulab@iscas.ac.cn +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ralink.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clocksource/timer-ralink.c b/drivers/clocksource/timer-ralink.c +index 6ecdb4228f763..68434d9ed9107 100644 +--- a/drivers/clocksource/timer-ralink.c ++++ b/drivers/clocksource/timer-ralink.c +@@ -130,14 +130,15 @@ static int __init ralink_systick_init(struct device_node *np) + systick.dev.irq = irq_of_parse_and_map(np, 0); + if (!systick.dev.irq) { + pr_err("%pOFn: request_irq failed", np); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_iounmap; + } + + ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, + SYSTICK_FREQ, 301, 16, + clocksource_mmio_readl_up); + if (ret) +- return ret; ++ goto err_free_irq; + + clockevents_register_device(&systick.dev); + +@@ -145,6 +146,12 @@ static int __init ralink_systick_init(struct device_node *np) + np, systick.dev.mult, systick.dev.shift); + + return 0; ++ ++err_free_irq: ++ irq_dispose_mapping(systick.dev.irq); ++err_iounmap: ++ iounmap(systick.membase); ++ return ret; + } + + TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init); +-- +2.51.0 + diff --git a/queue-6.17/clocksource-drivers-stm-fix-double-deregistration-on.patch b/queue-6.17/clocksource-drivers-stm-fix-double-deregistration-on.patch new file mode 100644 index 0000000000..b96cba8151 --- /dev/null +++ b/queue-6.17/clocksource-drivers-stm-fix-double-deregistration-on.patch @@ -0,0 +1,42 @@ +From bd315d53e486e1bec67302c2db895227674595c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 07:50:39 +0200 +Subject: clocksource/drivers/stm: Fix double deregistration on probe failure + +From: Johan Hovold + +[ Upstream commit 6b38a8b31e2c5c2c3fd5f9848850788c190f216d ] + +The purpose of the devm_add_action_or_reset() helper is to call the +action function in case adding an action ever fails so drop the clock +source deregistration from the error path to avoid deregistering twice. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Cc: Daniel Lezcano +Link: https://patch.msgid.link/20251017055039.7307-1-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index d7ccf90017298..8bca183abe8f2 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -207,10 +207,8 @@ static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer + return ret; + + ret = devm_add_action_or_reset(dev, devm_clocksource_unregister, stm_timer); +- if (ret) { +- clocksource_unregister(&stm_timer->cs); ++ if (ret) + return ret; +- } + + stm_sched_clock = stm_timer; + +-- +2.51.0 + diff --git a/queue-6.17/coresight-change-device-mode-to-atomic-type.patch b/queue-6.17/coresight-change-device-mode-to-atomic-type.patch new file mode 100644 index 0000000000..47fea1600f --- /dev/null +++ b/queue-6.17/coresight-change-device-mode-to-atomic-type.patch @@ -0,0 +1,91 @@ +From b48974bd79049668af6e7613831e6b8cc8734ce7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:35 +0000 +Subject: coresight: Change device mode to atomic type + +From: Leo Yan + +[ Upstream commit 693d1eaca940f277af24c74873ef2313816ff444 ] + +The device mode is defined as local type. This type cannot promise +SMP-safe access. + +Change to atomic type and impose relax ordering, which ensures the +SMP-safe synchronisation and the ordering between the mode setting and +relevant operations. + +Fixes: 22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()") +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-1-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + include/linux/coresight.h | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index ead03818d7d75..b2b7f09ac3823 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -252,15 +252,11 @@ struct coresight_trace_id_map { + * by @coresight_ops. + * @access: Device i/o access abstraction for this device. + * @dev: The device entity associated to this component. +- * @mode: This tracer's mode, i.e sysFS, Perf or disabled. This is +- * actually an 'enum cs_mode', but is stored in an atomic type. +- * This is always accessed through local_read() and local_set(), +- * but wherever it's done from within the Coresight device's lock, +- * a non-atomic read would also work. This is the main point of +- * synchronisation between code happening inside the sysfs mode's +- * coresight_mutex and outside when running in Perf mode. A compare +- * and exchange swap is done to atomically claim one mode or the +- * other. ++ * @mode: The device mode, i.e sysFS, Perf or disabled. This is actually ++ * an 'enum cs_mode' but stored in an atomic type. Access is always ++ * through atomic APIs, ensuring SMP-safe synchronisation between ++ * racing from sysFS and Perf mode. A compare-and-exchange ++ * operation is done to atomically claim one mode or the other. + * @refcnt: keep track of what is in use. Only access this outside of the + * device's spinlock when the coresight_mutex held and mode == + * CS_MODE_SYSFS. Otherwise it must be accessed from inside the +@@ -289,7 +285,7 @@ struct coresight_device { + const struct coresight_ops *ops; + struct csdev_access access; + struct device dev; +- local_t mode; ++ atomic_t mode; + int refcnt; + bool orphan; + /* sink specific fields */ +@@ -651,13 +647,14 @@ static inline bool coresight_is_percpu_sink(struct coresight_device *csdev) + static inline bool coresight_take_mode(struct coresight_device *csdev, + enum cs_mode new_mode) + { +- return local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, new_mode) == +- CS_MODE_DISABLED; ++ int curr = CS_MODE_DISABLED; ++ ++ return atomic_try_cmpxchg_acquire(&csdev->mode, &curr, new_mode); + } + + static inline enum cs_mode coresight_get_mode(struct coresight_device *csdev) + { +- return local_read(&csdev->mode); ++ return atomic_read_acquire(&csdev->mode); + } + + static inline void coresight_set_mode(struct coresight_device *csdev, +@@ -673,7 +670,7 @@ static inline void coresight_set_mode(struct coresight_device *csdev, + WARN(new_mode != CS_MODE_DISABLED && current_mode != CS_MODE_DISABLED && + current_mode != new_mode, "Device already in use\n"); + +- local_set(&csdev->mode, new_mode); ++ atomic_set_release(&csdev->mode, new_mode); + } + + struct coresight_device *coresight_register(struct coresight_desc *desc); +-- +2.51.0 + diff --git a/queue-6.17/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch b/queue-6.17/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch new file mode 100644 index 0000000000..f725da73ef --- /dev/null +++ b/queue-6.17/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch @@ -0,0 +1,176 @@ +From 60b8704292e8c68cc4911714ae915a1bc7c8987a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:37 +0000 +Subject: coresight: etm3x: Always set tracer's device mode on target CPU + +From: Leo Yan + +[ Upstream commit ab3fde32afe6a77e5cc60f868e44e6e09424752b ] + +The ETMv3 driver shares the same issue as ETMv4 regarding race +conditions when accessing the device mode. + +This commit applies the same fix: ensuring that the device mode is +modified only by the target CPU to eliminate race conditions across +CPUs. + +Fixes: 22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()") +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-3-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm3x-core.c | 59 +++++++++++++------ + 1 file changed, 40 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c +index baba2245b1dfb..602648eb33ec5 100644 +--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c +@@ -439,13 +439,26 @@ struct etm_enable_arg { + int rc; + }; + +-static void etm_enable_hw_smp_call(void *info) ++static void etm_enable_sysfs_smp_call(void *info) + { + struct etm_enable_arg *arg = info; ++ struct coresight_device *csdev; + + if (WARN_ON(!arg)) + return; ++ ++ csdev = arg->drvdata->csdev; ++ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) { ++ /* Someone is already using the tracer */ ++ arg->rc = -EBUSY; ++ return; ++ } ++ + arg->rc = etm_enable_hw(arg->drvdata); ++ ++ /* The tracer didn't start */ ++ if (arg->rc) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static int etm_cpu_id(struct coresight_device *csdev) +@@ -465,16 +478,26 @@ static int etm_enable_perf(struct coresight_device *csdev, + struct coresight_path *path) + { + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); ++ int ret; + + if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) + return -EINVAL; + ++ if (!coresight_take_mode(csdev, CS_MODE_PERF)) ++ return -EBUSY; ++ + /* Configure the tracer based on the session's specifics */ + etm_parse_event_config(drvdata, event); + drvdata->traceid = path->trace_id; + + /* And enable it */ +- return etm_enable_hw(drvdata); ++ ret = etm_enable_hw(drvdata); ++ ++ /* Failed to start tracer; roll back to DISABLED mode */ ++ if (ret) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); ++ ++ return ret; + } + + static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path) +@@ -494,7 +517,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat + if (cpu_online(drvdata->cpu)) { + arg.drvdata = drvdata; + ret = smp_call_function_single(drvdata->cpu, +- etm_enable_hw_smp_call, &arg, 1); ++ etm_enable_sysfs_smp_call, &arg, 1); + if (!ret) + ret = arg.rc; + if (!ret) +@@ -517,12 +540,6 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event, + enum cs_mode mode, struct coresight_path *path) + { + int ret; +- struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); +- +- if (!coresight_take_mode(csdev, mode)) { +- /* Someone is already using the tracer */ +- return -EBUSY; +- } + + switch (mode) { + case CS_MODE_SYSFS: +@@ -535,17 +552,12 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event, + ret = -EINVAL; + } + +- /* The tracer didn't start */ +- if (ret) +- coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); +- + return ret; + } + +-static void etm_disable_hw(void *info) ++static void etm_disable_hw(struct etm_drvdata *drvdata) + { + int i; +- struct etm_drvdata *drvdata = info; + struct etm_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + +@@ -567,6 +579,15 @@ static void etm_disable_hw(void *info) + "cpu: %d disable smp call done\n", drvdata->cpu); + } + ++static void etm_disable_sysfs_smp_call(void *info) ++{ ++ struct etm_drvdata *drvdata = info; ++ ++ etm_disable_hw(drvdata); ++ ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++} ++ + static void etm_disable_perf(struct coresight_device *csdev) + { + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); +@@ -588,6 +609,8 @@ static void etm_disable_perf(struct coresight_device *csdev) + + CS_LOCK(drvdata->csa.base); + ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++ + /* + * perf will release trace ids when _free_aux() + * is called at the end of the session +@@ -612,7 +635,8 @@ static void etm_disable_sysfs(struct coresight_device *csdev) + * Executing etm_disable_hw on the cpu whose ETM is being disabled + * ensures that register writes occur when cpu is powered. + */ +- smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1); ++ smp_call_function_single(drvdata->cpu, etm_disable_sysfs_smp_call, ++ drvdata, 1); + + spin_unlock(&drvdata->spinlock); + cpus_read_unlock(); +@@ -652,9 +676,6 @@ static void etm_disable(struct coresight_device *csdev, + WARN_ON_ONCE(mode); + return; + } +- +- if (mode) +- coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static const struct coresight_ops_source etm_source_ops = { +-- +2.51.0 + diff --git a/queue-6.17/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-6.17/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..06ec71d1fd --- /dev/null +++ b/queue-6.17/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From 5995a622e5a074d3d875c3d1599eb917523de60b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 1fa6d123b8143..668665cd437ad 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -446,10 +446,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -931,11 +945,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-6.17/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch b/queue-6.17/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch new file mode 100644 index 0000000000..8c6826427f --- /dev/null +++ b/queue-6.17/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch @@ -0,0 +1,230 @@ +From 6d6b13c0f89348610a8819d87c3373ea84e705c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:36 +0000 +Subject: coresight: etm4x: Always set tracer's device mode on target CPU + +From: Leo Yan + +[ Upstream commit 28eee2158575aea8fee7807adb9248ceaf9196f1 ] + +When enabling a tracer via SysFS interface, the device mode may be set +by any CPU - not necessarily the target CPU. This can lead to race +condition in SMP, and may result in incorrect mode values being read. + +Consider the following example, where CPU0 attempts to enable the tracer +on CPU1 (the target CPU): + + CPU0 CPU1 + etm4_enable() + ` coresight_take_mode(SYSFS) + ` etm4_enable_sysfs() + ` smp_call_function_single() ----> etm4_enable_hw_smp_call() + / + / CPU idle: + / etm4_cpu_save() + / ` coresight_get_mode() + Failed to enable h/w / ^^^ + ` coresight_set_mode(DISABLED) <-' Read the intermediate SYSFS mode + +In this case, CPU0 initiates the operation by taking the SYSFS mode to +avoid conflicts with the Perf mode. It then sends an IPI to CPU1 to +configure the tracer registers. If any error occurs during this process, +CPU0 rolls back by setting the mode to DISABLED. + +However, if CPU1 enters an idle state during this time, it might read +the intermediate SYSFS mode. As a result, the CPU PM flow could wrongly +save and restore tracer context that is actually disabled. + +To resolve the issue, this commit moves the device mode setting logic on +the target CPU. This ensures that the device mode is only modified by +the target CPU, eliminating race condition between mode writes and reads +across CPUs. + +An additional change introduces the etm4_disable_sysfs_smp_call() +function for SMP calls, which disables the tracer and explicitly set the +mode to DISABLED during SysFS operations. Rename +etm4_disable_hw_smp_call() to etm4_disable_sysfs_smp_call() for naming +consistency. + +The flow is updated with this change: + + CPU0 CPU1 + etm4_enable() + ` etm4_enable_sysfs() + ` smp_call_function_single() ----> etm4_enable_hw_smp_call() + ` coresight_take_mode(SYSFS) + Failed, set back to DISABLED + ` coresight_set_mode(DISABLED) + + CPU idle: + etm4_cpu_save() + ` coresight_get_mode() + ^^^ + Read out the DISABLED mode + +Fixes: c38a9ec2b2c1 ("coresight: etm4x: moving etm_drvdata::enable to atomic field") +Reviewed-by: Yeoreum Yun +Reviewed-by: mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-2-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 60 ++++++++++++------- + 1 file changed, 38 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 4b98a7bf4cb73..baf38142b317f 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -589,13 +589,26 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + return rc; + } + +-static void etm4_enable_hw_smp_call(void *info) ++static void etm4_enable_sysfs_smp_call(void *info) + { + struct etm4_enable_arg *arg = info; ++ struct coresight_device *csdev; + + if (WARN_ON(!arg)) + return; ++ ++ csdev = arg->drvdata->csdev; ++ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) { ++ /* Someone is already using the tracer */ ++ arg->rc = -EBUSY; ++ return; ++ } ++ + arg->rc = etm4_enable_hw(arg->drvdata); ++ ++ /* The tracer didn't start */ ++ if (arg->rc) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + /* +@@ -808,13 +821,14 @@ static int etm4_enable_perf(struct coresight_device *csdev, + struct perf_event *event, + struct coresight_path *path) + { +- int ret = 0; + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); ++ int ret; + +- if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) { +- ret = -EINVAL; +- goto out; +- } ++ if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) ++ return -EINVAL; ++ ++ if (!coresight_take_mode(csdev, CS_MODE_PERF)) ++ return -EBUSY; + + /* Configure the tracer based on the session's specifics */ + ret = etm4_parse_event_config(csdev, event); +@@ -830,6 +844,9 @@ static int etm4_enable_perf(struct coresight_device *csdev, + ret = etm4_enable_hw(drvdata); + + out: ++ /* Failed to start tracer; roll back to DISABLED mode */ ++ if (ret) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + return ret; + } + +@@ -861,7 +878,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa + */ + arg.drvdata = drvdata; + ret = smp_call_function_single(drvdata->cpu, +- etm4_enable_hw_smp_call, &arg, 1); ++ etm4_enable_sysfs_smp_call, &arg, 1); + if (!ret) + ret = arg.rc; + if (!ret) +@@ -882,11 +899,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + { + int ret; + +- if (!coresight_take_mode(csdev, mode)) { +- /* Someone is already using the tracer */ +- return -EBUSY; +- } +- + switch (mode) { + case CS_MODE_SYSFS: + ret = etm4_enable_sysfs(csdev, path); +@@ -898,10 +910,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + ret = -EINVAL; + } + +- /* The tracer didn't start */ +- if (ret) +- coresight_set_mode(csdev, CS_MODE_DISABLED); +- + return ret; + } + +@@ -953,10 +961,9 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + isb(); + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_hw(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; + struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct csdev_access *csa = &csdev->access; +@@ -993,6 +1000,15 @@ static void etm4_disable_hw(void *info) + "cpu: %d disable smp call done\n", drvdata->cpu); + } + ++static void etm4_disable_sysfs_smp_call(void *info) ++{ ++ struct etmv4_drvdata *drvdata = info; ++ ++ etm4_disable_hw(drvdata); ++ ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++} ++ + static int etm4_disable_perf(struct coresight_device *csdev, + struct perf_event *event) + { +@@ -1022,6 +1038,8 @@ static int etm4_disable_perf(struct coresight_device *csdev, + /* TRCVICTLR::SSSTATUS, bit[9] */ + filters->ssstatus = (control & BIT(9)); + ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++ + /* + * perf will release trace ids when _free_aux() is + * called at the end of the session. +@@ -1047,7 +1065,8 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) + * Executing etm4_disable_hw on the cpu whose ETM is being disabled + * ensures that register writes occur when cpu is powered. + */ +- smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1); ++ smp_call_function_single(drvdata->cpu, etm4_disable_sysfs_smp_call, ++ drvdata, 1); + + raw_spin_unlock(&drvdata->spinlock); + +@@ -1087,9 +1106,6 @@ static void etm4_disable(struct coresight_device *csdev, + etm4_disable_perf(csdev, event); + break; + } +- +- if (mode) +- coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static int etm4_resume_perf(struct coresight_device *csdev) +-- +2.51.0 + diff --git a/queue-6.17/coresight-etm4x-correct-polling-idle-bit.patch b/queue-6.17/coresight-etm4x-correct-polling-idle-bit.patch new file mode 100644 index 0000000000..e66589ebea --- /dev/null +++ b/queue-6.17/coresight-etm4x-correct-polling-idle-bit.patch @@ -0,0 +1,43 @@ +From d9eaf10533448e612698ea01eb886fbdb7c595dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:38 +0000 +Subject: coresight: etm4x: Correct polling IDLE bit + +From: Leo Yan + +[ Upstream commit 4dc4e22f9536341255f5de6047977a80ff47eaef ] + +Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading +the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit +instead of the IDLE bit. + +This commit corrects the typo. + +Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") +Reviewed-by: Yeoreum Yun +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index baf38142b317f..1fa6d123b8143 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1924,7 +1924,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +-- +2.51.0 + diff --git a/queue-6.17/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch b/queue-6.17/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch new file mode 100644 index 0000000000..b71cb2beb2 --- /dev/null +++ b/queue-6.17/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch @@ -0,0 +1,125 @@ +From befedc77c613918cd214184cc67f49d70cc8809f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:40 +0000 +Subject: coresight: etm4x: Properly control filter in CPU idle with FEAT_TRF + +From: Leo Yan + +[ Upstream commit 1fdc2cd347a7bc58acacb6144404ee892cea6c2e ] + +If a CPU supports FEAT_TRF, as described in the section K5.5 "Context +switching", Arm ARM (ARM DDI 0487 L.a), it defines a flow to prohibit +program-flow trace, execute a TSB CSYNC instruction for flushing, +followed by clearing TRCPRGCTLR.EN bit. + +To restore the state, the reverse sequence is required. + +This differs from the procedure described in the section 3.4.1 "The +procedure when powering down the PE" of ARM IHI0064H.b, which involves +the OS Lock to prevent external debugger accesses and implicitly +disables trace. + +To be compatible with different ETM versions, explicitly control trace +unit using etm4_disable_trace_unit() and etm4_enable_trace_unit() +during CPU idle to comply with FEAT_TRF. + +As a result, the save states for TRFCR_ELx and trcprgctlr are redundant, +remove them. + +Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states") +Reviewed-by: Mike Leach +Tested-by: James Clark +Reviewed-by: Yeoreum Yun +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-6-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 14 +++++++------- + drivers/hwtracing/coresight/coresight-etm4x.h | 3 --- + 2 files changed, 7 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 668665cd437ad..3906818e65c8a 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1858,9 +1858,11 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + goto out; + } + ++ if (!drvdata->paused) ++ etm4_disable_trace_unit(drvdata); ++ + state = drvdata->save_state; + +- state->trcprgctlr = etm4x_read32(csa, TRCPRGCTLR); + if (drvdata->nr_pe) + state->trcprocselr = etm4x_read32(csa, TRCPROCSELR); + state->trcconfigr = etm4x_read32(csa, TRCCONFIGR); +@@ -1970,9 +1972,6 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata) + { + int ret = 0; + +- /* Save the TRFCR irrespective of whether the ETM is ON */ +- if (drvdata->trfcr) +- drvdata->save_trfcr = read_trfcr(); + /* + * Save and restore the ETM Trace registers only if + * the ETM is active. +@@ -1994,7 +1993,6 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + etm4_cs_unlock(drvdata, csa); + etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET); + +- etm4x_relaxed_write32(csa, state->trcprgctlr, TRCPRGCTLR); + if (drvdata->nr_pe) + etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR); + etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR); +@@ -2079,13 +2077,15 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + + /* Unlock the OS lock to re-enable trace and external debug access */ + etm4_os_unlock(drvdata); ++ ++ if (!drvdata->paused) ++ etm4_enable_trace_unit(drvdata); ++ + etm4_cs_lock(drvdata, csa); + } + + static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) + { +- if (drvdata->trfcr) +- write_trfcr(drvdata->save_trfcr); + if (drvdata->state_needs_restore) + __etm4_cpu_restore(drvdata); + } +diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h +index 13ec9ecef46f5..b8796b4271025 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x.h ++++ b/drivers/hwtracing/coresight/coresight-etm4x.h +@@ -866,7 +866,6 @@ struct etmv4_config { + * struct etm4_save_state - state to be preserved when ETM is without power + */ + struct etmv4_save_state { +- u32 trcprgctlr; + u32 trcprocselr; + u32 trcconfigr; + u32 trcauxctlr; +@@ -980,7 +979,6 @@ struct etmv4_save_state { + * at runtime, due to the additional setting of TRFCR_CX when + * in EL2. Otherwise, 0. + * @config: structure holding configuration parameters. +- * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. + * @save_state: State to be preserved across power loss + * @state_needs_restore: True when there is context to restore after PM exit + * @skip_power_up: Indicates if an implementation can skip powering up +@@ -1037,7 +1035,6 @@ struct etmv4_drvdata { + bool lpoverride; + u64 trfcr; + struct etmv4_config config; +- u64 save_trfcr; + struct etmv4_save_state *save_state; + bool state_needs_restore; + bool skip_power_up; +-- +2.51.0 + diff --git a/queue-6.17/coresight-etr-fix-etr-buffer-use-after-free-issue.patch b/queue-6.17/coresight-etr-fix-etr-buffer-use-after-free-issue.patch new file mode 100644 index 0000000000..5aa9384f80 --- /dev/null +++ b/queue-6.17/coresight-etr-fix-etr-buffer-use-after-free-issue.patch @@ -0,0 +1,50 @@ +From e312e48831a66cc16e73bc34b15b579a101917bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 16:45:25 +0800 +Subject: coresight: ETR: Fix ETR buffer use-after-free issue + +From: Xiaoqi Zhuang + +[ Upstream commit 35501ac3c7d40a7bb9568c2f89d6b56beaf9bed3 ] + +When ETR is enabled as CS_MODE_SYSFS, if the buffer size is changed +and enabled again, currently sysfs_buf will point to the newly +allocated memory(buf_new) and free the old memory(buf_old). But the +etr_buf that is being used by the ETR remains pointed to buf_old, not +updated to buf_new. In this case, it will result in a memory +use-after-free issue. + +Fix this by checking ETR's mode before updating and releasing buf_old, +if the mode is CS_MODE_SYSFS, then skip updating and releasing it. + +Fixes: bd2767ec3df2 ("coresight: Fix run time warnings while reusing ETR buffer") +Signed-off-by: Xiaoqi Zhuang +Signed-off-by: Suzuki K Poulose +Tested-by: Leo Yan +Link: https://lore.kernel.org/r/20251021-fix_etr_issue-v3-1-99a2d066fee2@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-tmc-etr.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c +index b07fcdb3fe1a8..800be06598c1b 100644 +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1250,6 +1250,13 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) + * with the lock released. + */ + raw_spin_lock_irqsave(&drvdata->spinlock, flags); ++ ++ /* ++ * If the ETR is already enabled, continue with the existing buffer. ++ */ ++ if (coresight_get_mode(csdev) == CS_MODE_SYSFS) ++ goto out; ++ + sysfs_buf = READ_ONCE(drvdata->sysfs_buf); + if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); +-- +2.51.0 + diff --git a/queue-6.17/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch b/queue-6.17/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch new file mode 100644 index 0000000000..dccb101741 --- /dev/null +++ b/queue-6.17/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch @@ -0,0 +1,91 @@ +From 1f182f397e8d159dde8f4c3c678d6d9c3cb5f7f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 18:42:31 +0800 +Subject: coresight: tmc: add the handle of the event to the path + +From: Carl Worth + +[ Upstream commit aaa5abcc9d44d2c8484f779ab46d242d774cabcb ] + +The handle is essential for retrieving the AUX_EVENT of each CPU and is +required in perf mode. It has been added to the coresight_path so that +dependent devices can access it from the path when needed. + +The existing bug can be reproduced with: +perf record -e cs_etm//k -C 0-9 dd if=/dev/zero of=/dev/null + +Showing an oops as follows: +Unable to handle kernel paging request at virtual address 000f6e84934ed19e + +Call trace: + tmc_etr_get_buffer+0x30/0x80 [coresight_tmc] (P) + catu_enable_hw+0xbc/0x3d0 [coresight_catu] + catu_enable+0x70/0xe0 [coresight_catu] + coresight_enable_path+0xb0/0x258 [coresight] + +Fixes: 080ee83cc361 ("Coresight: Change functions to accept the coresight_path") +Signed-off-by: Carl Worth +Reviewed-by: Leo Yan +Co-developed-by: Jie Gan +Signed-off-by: Jie Gan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250925-fix_helper_data-v2-1-edd8a07c1646@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm-perf.c | 1 + + drivers/hwtracing/coresight/coresight-tmc-etr.c | 3 ++- + include/linux/coresight.h | 10 ++++++---- + 3 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c +index f1551c08ecb20..20fdd09b75c93 100644 +--- a/drivers/hwtracing/coresight/coresight-etm-perf.c ++++ b/drivers/hwtracing/coresight/coresight-etm-perf.c +@@ -520,6 +520,7 @@ static void etm_event_start(struct perf_event *event, int flags) + goto out; + + path = etm_event_cpu_path(event_data, cpu); ++ path->handle = handle; + /* We need a sink, no need to continue without one */ + sink = coresight_get_sink(path); + if (WARN_ON_ONCE(!sink)) +diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c +index 800be06598c1b..60b0e0a6da057 100644 +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1334,7 +1334,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) + struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, + enum cs_mode mode, void *data) + { +- struct perf_output_handle *handle = data; ++ struct coresight_path *path = data; ++ struct perf_output_handle *handle = path->handle; + struct etr_perf_buffer *etr_perf; + + switch (mode) { +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index bb49080ec8f96..ead03818d7d75 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -333,12 +333,14 @@ static struct coresight_dev_list (var) = { \ + + /** + * struct coresight_path - data needed by enable/disable path +- * @path_list: path from source to sink. +- * @trace_id: trace_id of the whole path. ++ * @path_list: path from source to sink. ++ * @trace_id: trace_id of the whole path. ++ * @handle: handle of the aux_event. + */ + struct coresight_path { +- struct list_head path_list; +- u8 trace_id; ++ struct list_head path_list; ++ u8 trace_id; ++ struct perf_output_handle *handle; + }; + + enum cs_mode { +-- +2.51.0 + diff --git a/queue-6.17/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch b/queue-6.17/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch new file mode 100644 index 0000000000..42eddad629 --- /dev/null +++ b/queue-6.17/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch @@ -0,0 +1,44 @@ +From 818f46fcf4632bf475e39db232dcfdd1a52d7b8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 13:11:45 +0530 +Subject: cpufreq/amd-pstate: Call cppc_set_auto_sel() only for online CPUs + +From: Gautham R. Shenoy + +[ Upstream commit bb31fef0d03ed17d587b40e3458786be408fb9df ] + +amd_pstate_change_mode_without_dvr_change() calls cppc_set_auto_sel() +for all the present CPUs. + +However, this callpath eventually calls cppc_set_reg_val() which +accesses the per-cpu cpc_desc_ptr object. This object is initialized +only for online CPUs via acpi_soft_cpu_online() --> +__acpi_processor_start() --> acpi_cppc_processor_probe(). + +Hence, restrict calling cppc_set_auto_sel() to only the online CPUs. + +Fixes: 3ca7bc818d8c ("cpufreq: amd-pstate: Add guided mode control support via sysfs") +Suggested-by: Mario Limonciello (AMD) (kernel.org) +Signed-off-by: Gautham R. Shenoy +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd-pstate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index e4f1933dd7d47..7be26007f1d8e 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -1282,7 +1282,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode) + if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE) + return 0; + +- for_each_present_cpu(cpu) { ++ for_each_online_cpu(cpu) { + cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1); + } + +-- +2.51.0 + diff --git a/queue-6.17/cpuset-treat-cpusets-in-attaching-as-populated.patch b/queue-6.17/cpuset-treat-cpusets-in-attaching-as-populated.patch new file mode 100644 index 0000000000..8d33ce87ee --- /dev/null +++ b/queue-6.17/cpuset-treat-cpusets-in-attaching-as-populated.patch @@ -0,0 +1,115 @@ +From 77360722722111a5986fa0ee5062633a3b6aa7c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 02:08:47 +0000 +Subject: cpuset: Treat cpusets in attaching as populated + +From: Chen Ridong + +[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ] + +Currently, the check for whether a partition is populated does not +account for tasks in the cpuset of attaching. This is a corner case +that can leave a task stuck in a partition with no effective CPUs. + +The race condition occurs as follows: + +cpu0 cpu1 + //cpuset A with cpu N +migrate task p to A +cpuset_can_attach +// with effective cpus +// check ok + +// cpuset_mutex is not held // clear cpuset.cpus.exclusive + // making effective cpus empty + update_exclusive_cpumask + // tasks_nocpu_error check ok + // empty effective cpus, partition valid +cpuset_attach +... +// task p stays in A, with non-effective cpus. + +To fix this issue, this patch introduces cs_is_populated, which considers +tasks in the attaching cpuset. This new helper is used in validate_change +and partition_is_populated. + +Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") +Signed-off-by: Chen Ridong +Reviewed-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index fd890b34a8403..06a58f62be58c 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -327,6 +327,15 @@ static inline bool is_in_v2_mode(void) + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); + } + ++static inline bool cpuset_is_populated(struct cpuset *cs) ++{ ++ lockdep_assert_held(&cpuset_mutex); ++ ++ /* Cpusets in the process of attaching should be considered as populated */ ++ return cgroup_is_populated(cs->css.cgroup) || ++ cs->attach_in_progress; ++} ++ + /** + * partition_is_populated - check if partition has tasks + * @cs: partition root to be checked +@@ -339,21 +348,31 @@ static inline bool is_in_v2_mode(void) + static inline bool partition_is_populated(struct cpuset *cs, + struct cpuset *excluded_child) + { +- struct cgroup_subsys_state *css; +- struct cpuset *child; ++ struct cpuset *cp; ++ struct cgroup_subsys_state *pos_css; + +- if (cs->css.cgroup->nr_populated_csets) ++ /* ++ * We cannot call cs_is_populated(cs) directly, as ++ * nr_populated_domain_children may include populated ++ * csets from descendants that are partitions. ++ */ ++ if (cs->css.cgroup->nr_populated_csets || ++ cs->attach_in_progress) + return true; + if (!excluded_child && !cs->nr_subparts) + return cgroup_is_populated(cs->css.cgroup); + + rcu_read_lock(); +- cpuset_for_each_child(child, css, cs) { +- if (child == excluded_child) ++ cpuset_for_each_descendant_pre(cp, pos_css, cs) { ++ if (cp == cs || cp == excluded_child) + continue; +- if (is_partition_valid(child)) ++ ++ if (is_partition_valid(cp)) { ++ pos_css = css_rightmost_descendant(pos_css); + continue; +- if (cgroup_is_populated(child->css.cgroup)) { ++ } ++ ++ if (cpuset_is_populated(cp)) { + rcu_read_unlock(); + return true; + } +@@ -584,7 +603,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) + * be changed to have empty cpus_allowed or mems_allowed. + */ + ret = -ENOSPC; +- if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { ++ if (cpuset_is_populated(cur)) { + if (!cpumask_empty(cur->cpus_allowed) && + cpumask_empty(trial->cpus_allowed)) + goto out; +-- +2.51.0 + diff --git a/queue-6.17/crypto-aead-fix-reqsize-handling.patch b/queue-6.17/crypto-aead-fix-reqsize-handling.patch new file mode 100644 index 0000000000..6ae6092fe1 --- /dev/null +++ b/queue-6.17/crypto-aead-fix-reqsize-handling.patch @@ -0,0 +1,49 @@ +From 7e8ce4fbc316f59421e9bc05d2d28f4e2afeeb4d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:03:14 +0530 +Subject: crypto: aead - Fix reqsize handling + +From: T Pratham + +[ Upstream commit 9b04d8f00569573796dd05397f5779135593eb24 ] + +Commit afddce13ce81d ("crypto: api - Add reqsize to crypto_alg") +introduced cra_reqsize field in crypto_alg struct to replace type +specific reqsize fields. It looks like this was introduced specifically +for ahash and acomp from the commit description as subsequent commits +add necessary changes in these alg frameworks. + +However, this is being recommended for use in all crypto algs +instead of setting reqsize using crypto_*_set_reqsize(). Using +cra_reqsize in aead algorithms, hence, causes memory corruptions and +crashes as the underlying functions in the algorithm framework have not +been updated to set the reqsize properly from cra_reqsize. [1] + +Add proper set_reqsize calls in the aead init function to properly +initialize reqsize for these algorithms in the framework. + +[1]: https://gist.github.com/Pratham-T/24247446f1faf4b7843e4014d5089f6b + +Fixes: afddce13ce81d ("crypto: api - Add reqsize to crypto_alg") +Signed-off-by: T Pratham +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/aead.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/aead.c b/crypto/aead.c +index 5d14b775036ee..51ab3af691af2 100644 +--- a/crypto/aead.c ++++ b/crypto/aead.c +@@ -120,6 +120,7 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm) + struct aead_alg *alg = crypto_aead_alg(aead); + + crypto_aead_set_flags(aead, CRYPTO_TFM_NEED_KEY); ++ crypto_aead_set_reqsize(aead, crypto_tfm_alg_reqsize(tfm)); + + aead->authsize = alg->maxauthsize; + +-- +2.51.0 + diff --git a/queue-6.17/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch b/queue-6.17/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch new file mode 100644 index 0000000000..32de655e64 --- /dev/null +++ b/queue-6.17/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch @@ -0,0 +1,60 @@ +From 13135f5e9face168ad3ecd189264277a1c498e2c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 13:36:03 +0800 +Subject: crypto: ahash - Fix crypto_ahash_import with partial block data + +From: Herbert Xu + +[ Upstream commit b0356b75f42fde15d4be268c5891f2cee6eb65bf ] + +Restore the partial block buffer in crypto_ahash_import by copying +it. Check whether the partial block buffer exceeds the maximum +size and return -EOVERFLOW if it does. + +Zero the partial block buffer in crypto_ahash_import_core. + +Reported-by: T Pratham +Tested-by: T Pratham +Fixes: 9d7a0ab1c753 ("crypto: ahash - Handle partial blocks in API") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ahash.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index a227793d2c5b5..5248aab939ca7 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -661,6 +661,12 @@ int crypto_ahash_import_core(struct ahash_request *req, const void *in) + in); + if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) + return -ENOKEY; ++ if (crypto_ahash_block_only(tfm)) { ++ unsigned int reqsize = crypto_ahash_reqsize(tfm); ++ u8 *buf = ahash_request_ctx(req); ++ ++ buf[reqsize - 1] = 0; ++ } + return crypto_ahash_alg(tfm)->import_core(req, in); + } + EXPORT_SYMBOL_GPL(crypto_ahash_import_core); +@@ -674,10 +680,14 @@ int crypto_ahash_import(struct ahash_request *req, const void *in) + if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) + return -ENOKEY; + if (crypto_ahash_block_only(tfm)) { ++ unsigned int plen = crypto_ahash_blocksize(tfm) + 1; + unsigned int reqsize = crypto_ahash_reqsize(tfm); ++ unsigned int ss = crypto_ahash_statesize(tfm); + u8 *buf = ahash_request_ctx(req); + +- buf[reqsize - 1] = 0; ++ memcpy(buf + reqsize - plen, in + ss - plen, plen); ++ if (buf[reqsize - 1] >= plen) ++ return -EOVERFLOW; + } + return crypto_ahash_alg(tfm)->import(req, in); + } +-- +2.51.0 + diff --git a/queue-6.17/crypto-ahash-zero-positive-err-value-in-ahash_update.patch b/queue-6.17/crypto-ahash-zero-positive-err-value-in-ahash_update.patch new file mode 100644 index 0000000000..7347b1eda7 --- /dev/null +++ b/queue-6.17/crypto-ahash-zero-positive-err-value-in-ahash_update.patch @@ -0,0 +1,44 @@ +From 59076ba160f622d3770248cabdbc6b56d866b525 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 13:54:20 +0800 +Subject: crypto: ahash - Zero positive err value in ahash_update_finish + +From: Herbert Xu + +[ Upstream commit ebbdf6466b30e3b37f3b360826efd21f0633fb9e ] + +The partial block length returned by a block-only driver should +not be passed up to the caller since ahash itself deals with the +partial block data. + +Set err to zero in ahash_update_finish if it was positive. + +Reported-by: T Pratham +Tested-by: T Pratham +Fixes: 9d7a0ab1c753 ("crypto: ahash - Handle partial blocks in API") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ahash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index 5248aab939ca7..09a02ed4c4a09 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -423,7 +423,11 @@ static int ahash_update_finish(struct ahash_request *req, int err) + + req->nbytes += nonzero - blen; + +- blen = err < 0 ? 0 : err + nonzero; ++ blen = 0; ++ if (err >= 0) { ++ blen = err + nonzero; ++ err = 0; ++ } + if (ahash_request_isvirt(req)) + memcpy(buf, req->svirt + req->nbytes - blen, blen); + else +-- +2.51.0 + diff --git a/queue-6.17/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-6.17/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..b298f03442 --- /dev/null +++ b/queue-6.17/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From ed9442d442830d5b84dc7e40d79f1ac9f4bb6b7a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index ba2d9d1ea235a..348966ea2175c 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -141,12 +142,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-6.17/crypto-authenc-correctly-pass-einprogress-back-up-to.patch b/queue-6.17/crypto-authenc-correctly-pass-einprogress-back-up-to.patch new file mode 100644 index 0000000000..3b909bf5a0 --- /dev/null +++ b/queue-6.17/crypto-authenc-correctly-pass-einprogress-back-up-to.patch @@ -0,0 +1,202 @@ +From 11f669789c9b4dd5075e22aa084a5d5e65259796 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 18:20:17 +0800 +Subject: crypto: authenc - Correctly pass EINPROGRESS back up to the caller + +From: Herbert Xu + +[ Upstream commit 96feb73def02d175850daa0e7c2c90c876681b5c ] + +When authenc is invoked with MAY_BACKLOG, it needs to pass EINPROGRESS +notifications back up to the caller when the underlying algorithm +returns EBUSY synchronously. + +However, if the EBUSY comes from the second part of an authenc call, +i.e., it is asynchronous, both the EBUSY and the subsequent EINPROGRESS +notification must not be passed to the caller. + +Implement this by passing a mask to the function that starts the +second half of authenc and using it to determine whether EBUSY +and EINPROGRESS should be passed to the caller. + +This was a deficiency in the original implementation of authenc +because it was not expected to be used with MAY_BACKLOG. + +Reported-by: Ingo Franzki +Reported-by: Mikulas Patocka +Fixes: 180ce7e81030 ("crypto: authenc - Add EINPROGRESS check") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/authenc.c | 75 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/crypto/authenc.c b/crypto/authenc.c +index a723769c87779..ac679ce2cb953 100644 +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -37,7 +37,7 @@ struct authenc_request_ctx { + + static void authenc_request_complete(struct aead_request *req, int err) + { +- if (err != -EINPROGRESS) ++ if (err != -EINPROGRESS && err != -EBUSY) + aead_request_complete(req, err); + } + +@@ -107,27 +107,42 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, + return err; + } + +-static void authenc_geniv_ahash_done(void *data, int err) ++static void authenc_geniv_ahash_finish(struct aead_request *req) + { +- struct aead_request *req = data; + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); + struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + +- if (err) +- goto out; +- + scatterwalk_map_and_copy(ahreq->result, req->dst, + req->assoclen + req->cryptlen, + crypto_aead_authsize(authenc), 1); ++} + +-out: ++static void authenc_geniv_ahash_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); + aead_request_complete(req, err); + } + +-static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ++/* ++ * Used when the ahash request was invoked in the async callback context ++ * of the previous skcipher request. Eat any EINPROGRESS notifications. ++ */ ++static void authenc_geniv_ahash_done2(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); ++ authenc_request_complete(req, err); ++} ++ ++static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -136,6 +151,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + struct crypto_ahash *auth = ctx->auth; + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *hash = areq_ctx->tail; + int err; + +@@ -143,7 +159,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + ahash_request_set_crypt(ahreq, req->dst, hash, + req->assoclen + req->cryptlen); + ahash_request_set_callback(ahreq, flags, +- authenc_geniv_ahash_done, req); ++ mask ? authenc_geniv_ahash_done2 : ++ authenc_geniv_ahash_done, req); + + err = crypto_ahash_digest(ahreq); + if (err) +@@ -159,12 +176,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) + { + struct aead_request *areq = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_genicv(areq, 0); +- +-out: ++ if (err) { ++ aead_request_complete(areq, err); ++ return; ++ } ++ err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(areq, err); + } + +@@ -199,11 +215,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_genicv(req, aead_request_flags(req)); ++ return crypto_authenc_genicv(req, 0); ++} ++ ++static void authenc_decrypt_tail_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ authenc_request_complete(req, err); + } + + static int crypto_authenc_decrypt_tail(struct aead_request *req, +- unsigned int flags) ++ unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -214,6 +237,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + struct skcipher_request *skreq = (void *)(areq_ctx->tail + + ictx->reqoff); + unsigned int authsize = crypto_aead_authsize(authenc); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *ihash = ahreq->result + authsize; + struct scatterlist *src, *dst; + +@@ -230,7 +254,9 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + + skcipher_request_set_tfm(skreq, ctx->enc); + skcipher_request_set_callback(skreq, flags, +- req->base.complete, req->base.data); ++ mask ? authenc_decrypt_tail_done : ++ req->base.complete, ++ mask ? req : req->base.data); + skcipher_request_set_crypt(skreq, src, dst, + req->cryptlen - authsize, req->iv); + +@@ -241,12 +267,11 @@ static void authenc_verify_ahash_done(void *data, int err) + { + struct aead_request *req = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_decrypt_tail(req, 0); +- +-out: ++ if (err) { ++ aead_request_complete(req, err); ++ return; ++ } ++ err = crypto_authenc_decrypt_tail(req, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(req, err); + } + +@@ -273,7 +298,7 @@ static int crypto_authenc_decrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); ++ return crypto_authenc_decrypt_tail(req, 0); + } + + static int crypto_authenc_init_tfm(struct crypto_aead *tfm) +-- +2.51.0 + diff --git a/queue-6.17/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-6.17/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..502866e75b --- /dev/null +++ b/queue-6.17/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From c25f14520d40c166c85199e325cb46186a58eac1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index 3963bb91321fc..dc7e0cd51c259 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%p curr_buff_cnt=0x%X nbytes=0x%X src=%p curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%p *curr_buff_cnt=0x%X copy_to=%p\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-6.17/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-6.17/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..aeeb1e6567 --- /dev/null +++ b/queue-6.17/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From c31e91b185de1375494642fa2de6bc0c32c785ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 60fe8cc9a7d05..dae2e4c36e53a 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3664,6 +3664,7 @@ static void qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -3671,6 +3672,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -3684,11 +3686,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-6.17/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch b/queue-6.17/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch new file mode 100644 index 0000000000..b64f3cbf6b --- /dev/null +++ b/queue-6.17/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch @@ -0,0 +1,40 @@ +From de0ab115e22d4bbe1388945da0b11cedcb28fe32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:56:48 +0000 +Subject: crypto: iaa - Fix incorrect return value in save_iaa_wq() + +From: Zilin Guan + +[ Upstream commit 76ce17f6f7f78ab79b9741388bdb4dafa985b4e9 ] + +The save_iaa_wq() function unconditionally returns 0, even when an error +is encountered. This prevents the error code from being propagated to the +caller. + +Fix this by returning the 'ret' variable, which holds the actual status +of the operations within the function. + +Fixes: ea7a5cbb43696 ("crypto: iaa - Add Intel IAA Compression Accelerator crypto driver core") +Signed-off-by: Zilin Guan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/iaa/iaa_crypto_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c +index 23f585219fb4b..d0058757b0000 100644 +--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c ++++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c +@@ -805,7 +805,7 @@ static int save_iaa_wq(struct idxd_wq *wq) + if (!cpus_per_iaa) + cpus_per_iaa = 1; + out: +- return 0; ++ return ret; + } + + static void remove_iaa_wq(struct idxd_wq *wq) +-- +2.51.0 + diff --git a/queue-6.17/crypto-starfive-correctly-handle-return-of-sg_nents_.patch b/queue-6.17/crypto-starfive-correctly-handle-return-of-sg_nents_.patch new file mode 100644 index 0000000000..6f4e4e5e44 --- /dev/null +++ b/queue-6.17/crypto-starfive-correctly-handle-return-of-sg_nents_.patch @@ -0,0 +1,51 @@ +From ba0185eb666006be25c2c04437121491df60b682 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:54:38 +0800 +Subject: crypto: starfive - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit e9eb52037a529fbb307c290e9951a62dd728b03d ] + +The return value of sg_nents_for_len was assigned to an unsigned long +in starfive_hash_digest, causing negative error codes to be converted +to large positive integers. + +Add error checking for sg_nents_for_len and return immediately on +failure to prevent potential buffer overflows. + +Fixes: 7883d1b28a2b ("crypto: starfive - Add hash and HMAC support") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-hash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c +index 6cfe0238f615f..66a8b04c0a55b 100644 +--- a/drivers/crypto/starfive/jh7110-hash.c ++++ b/drivers/crypto/starfive/jh7110-hash.c +@@ -326,6 +326,7 @@ static int starfive_hash_digest(struct ahash_request *req) + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_dev *cryp = ctx->cryp; ++ int sg_len; + + memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); + +@@ -334,7 +335,10 @@ static int starfive_hash_digest(struct ahash_request *req) + rctx->in_sg = req->src; + rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + rctx->digsize = crypto_ahash_digestsize(tfm); +- rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ if (sg_len < 0) ++ return sg_len; ++ rctx->in_sg_len = sg_len; + ctx->rctx = rctx; + + return crypto_transfer_hash_request_to_engine(cryp->engine, req); +-- +2.51.0 + diff --git a/queue-6.17/docs-kdoc-fix-duplicate-section-warning-message.patch b/queue-6.17/docs-kdoc-fix-duplicate-section-warning-message.patch new file mode 100644 index 0000000000..591dde3aff --- /dev/null +++ b/queue-6.17/docs-kdoc-fix-duplicate-section-warning-message.patch @@ -0,0 +1,107 @@ +From b848c5692d66aa0123bf4ef843c4d270b9f1095a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 12:58:32 -0700 +Subject: docs: kdoc: fix duplicate section warning message + +From: Jacob Keller + +[ Upstream commit e5e7ca66a7fc6b8073c30a048e1157b88d427980 ] + +The python version of the kernel-doc parser emits some strange warnings +with just a line number in certain cases: + +$ ./scripts/kernel-doc -Wall -none 'include/linux/virtio_config.h' +Warning: 174 +Warning: 184 +Warning: 190 +Warning: include/linux/virtio_config.h:226 No description found for return value of '__virtio_test_bit' +Warning: include/linux/virtio_config.h:259 No description found for return value of 'virtio_has_feature' +Warning: include/linux/virtio_config.h:283 No description found for return value of 'virtio_has_dma_quirk' +Warning: include/linux/virtio_config.h:392 No description found for return value of 'virtqueue_set_affinity' + +I eventually tracked this down to the lone call of emit_msg() in the +KernelEntry class, which looks like: + + self.emit_msg(self.new_start_line, f"duplicate section name '{name}'\n") + +This looks like all the other emit_msg calls. Unfortunately, the definition +within the KernelEntry class takes only a message parameter and not a line +number. The intended message is passed as the warning! + +Pass the filename to the KernelEntry class, and use this to build the log +message in the same way as the KernelDoc class does. + +To avoid future errors, mark the warning parameter for both emit_msg +definitions as a keyword-only argument. This will prevent accidentally +passing a string as the warning parameter in the future. + +Also fix the call in dump_section to avoid an unnecessary additional +newline. + +Fixes: e3b42e94cf10 ("scripts/lib/kdoc/kdoc_parser.py: move kernel entry to a class") +Signed-off-by: Jacob Keller +Signed-off-by: Jonathan Corbet +Message-ID: <20251030-jk-fix-kernel-doc-duplicate-return-warning-v2-1-ec4b5c662881@intel.com> +Signed-off-by: Sasha Levin +--- + scripts/lib/kdoc/kdoc_parser.py | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py +index fe730099eca86..386e4938c9c76 100644 +--- a/scripts/lib/kdoc/kdoc_parser.py ++++ b/scripts/lib/kdoc/kdoc_parser.py +@@ -134,6 +134,8 @@ class KernelEntry: + + self.leading_space = None + ++ self.fname = fname ++ + # State flags + self.brcount = 0 + self.declaration_start_line = ln + 1 +@@ -148,9 +150,11 @@ class KernelEntry: + return '\n'.join(self._contents) + '\n' + + # TODO: rename to emit_message after removal of kernel-doc.pl +- def emit_msg(self, log_msg, warning=True): ++ def emit_msg(self, ln, msg, *, warning=True): + """Emit a message""" + ++ log_msg = f"{self.fname}:{ln} {msg}" ++ + if not warning: + self.config.log.info(log_msg) + return +@@ -196,7 +200,7 @@ class KernelEntry: + # Only warn on user-specified duplicate section names + if name != SECTION_DEFAULT: + self.emit_msg(self.new_start_line, +- f"duplicate section name '{name}'\n") ++ f"duplicate section name '{name}'") + # Treat as a new paragraph - add a blank line + self.sections[name] += '\n' + contents + else: +@@ -247,15 +251,15 @@ class KernelDoc: + self.emit_msg(0, + 'Python 3.7 or later is required for correct results') + +- def emit_msg(self, ln, msg, warning=True): ++ def emit_msg(self, ln, msg, *, warning=True): + """Emit a message""" + +- log_msg = f"{self.fname}:{ln} {msg}" +- + if self.entry: +- self.entry.emit_msg(log_msg, warning) ++ self.entry.emit_msg(ln, msg, warning=warning) + return + ++ log_msg = f"{self.fname}:{ln} {msg}" ++ + if warning: + self.config.log.warning(log_msg) + else: +-- +2.51.0 + diff --git a/queue-6.17/drivers-hv-allocate-encrypted-buffers-when-requested.patch b/queue-6.17/drivers-hv-allocate-encrypted-buffers-when-requested.patch new file mode 100644 index 0000000000..0812549b99 --- /dev/null +++ b/queue-6.17/drivers-hv-allocate-encrypted-buffers-when-requested.patch @@ -0,0 +1,151 @@ +From 8c7f822d930cf4aec45b8794cc68dbae34651849 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:34:15 -0700 +Subject: Drivers: hv: Allocate encrypted buffers when requested + +From: Roman Kisel + +[ Upstream commit 0a4534bdf29a5b7f5a355c267d28dad9c40ba252 ] + +Confidential VMBus is built around using buffers not shared with +the host. + +Support allocating encrypted buffers when requested. + +Signed-off-by: Roman Kisel +Reviewed-by: Tianyu Lan +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Stable-dep-of: 510164539f16 ("Drivers: hv: Free msginfo when the buffer fails to decrypt") +Signed-off-by: Sasha Levin +--- + drivers/hv/channel.c | 49 +++++++++++++++++++++++---------------- + drivers/hv/hyperv_vmbus.h | 3 ++- + drivers/hv/ring_buffer.c | 5 ++-- + 3 files changed, 34 insertions(+), 23 deletions(-) + +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 7c7c66e0dc3f2..1621b95263a5b 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -444,20 +444,23 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, + return ret; + } + +- /* +- * Set the "decrypted" flag to true for the set_memory_decrypted() +- * success case. In the failure case, the encryption state of the +- * memory is unknown. Leave "decrypted" as true to ensure the +- * memory will be leaked instead of going back on the free list. +- */ +- gpadl->decrypted = true; +- ret = set_memory_decrypted((unsigned long)kbuffer, +- PFN_UP(size)); +- if (ret) { +- dev_warn(&channel->device_obj->device, +- "Failed to set host visibility for new GPADL %d.\n", +- ret); +- return ret; ++ gpadl->decrypted = !((channel->co_external_memory && type == HV_GPADL_BUFFER) || ++ (channel->co_ring_buffer && type == HV_GPADL_RING)); ++ if (gpadl->decrypted) { ++ /* ++ * The "decrypted" flag being true assumes that set_memory_decrypted() succeeds. ++ * But if it fails, the encryption state of the memory is unknown. In that case, ++ * leave "decrypted" as true to ensure the memory is leaked instead of going back ++ * on the free list. ++ */ ++ ret = set_memory_decrypted((unsigned long)kbuffer, ++ PFN_UP(size)); ++ if (ret) { ++ dev_warn(&channel->device_obj->device, ++ "Failed to set host visibility for new GPADL %d.\n", ++ ret); ++ return ret; ++ } + } + + init_completion(&msginfo->waitevent); +@@ -545,8 +548,10 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, + * left as true so the memory is leaked instead of being + * put back on the free list. + */ +- if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size))) +- gpadl->decrypted = false; ++ if (gpadl->decrypted) { ++ if (!set_memory_encrypted((unsigned long)kbuffer, PFN_UP(size))) ++ gpadl->decrypted = false; ++ } + } + + return ret; +@@ -677,12 +682,13 @@ static int __vmbus_open(struct vmbus_channel *newchannel, + goto error_clean_ring; + + err = hv_ringbuffer_init(&newchannel->outbound, +- page, send_pages, 0); ++ page, send_pages, 0, newchannel->co_ring_buffer); + if (err) + goto error_free_gpadl; + + err = hv_ringbuffer_init(&newchannel->inbound, &page[send_pages], +- recv_pages, newchannel->max_pkt_size); ++ recv_pages, newchannel->max_pkt_size, ++ newchannel->co_ring_buffer); + if (err) + goto error_free_gpadl; + +@@ -863,8 +869,11 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, struct vmbus_gpadl *gpad + + kfree(info); + +- ret = set_memory_encrypted((unsigned long)gpadl->buffer, +- PFN_UP(gpadl->size)); ++ if (gpadl->decrypted) ++ ret = set_memory_encrypted((unsigned long)gpadl->buffer, ++ PFN_UP(gpadl->size)); ++ else ++ ret = 0; + if (ret) + pr_warn("Fail to set mem host visibility in GPADL teardown %d.\n", ret); + +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index 4a01797d48513..0d969f77388ef 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -182,7 +182,8 @@ extern int hv_synic_cleanup(unsigned int cpu); + void hv_ringbuffer_pre_init(struct vmbus_channel *channel); + + int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, +- struct page *pages, u32 pagecnt, u32 max_pkt_size); ++ struct page *pages, u32 pagecnt, u32 max_pkt_size, ++ bool confidential); + + void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); + +diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c +index 23ce1fb70de14..3c421a7f78c00 100644 +--- a/drivers/hv/ring_buffer.c ++++ b/drivers/hv/ring_buffer.c +@@ -184,7 +184,8 @@ void hv_ringbuffer_pre_init(struct vmbus_channel *channel) + + /* Initialize the ring buffer. */ + int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, +- struct page *pages, u32 page_cnt, u32 max_pkt_size) ++ struct page *pages, u32 page_cnt, u32 max_pkt_size, ++ bool confidential) + { + struct page **pages_wraparound; + int i; +@@ -208,7 +209,7 @@ int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, + + ring_info->ring_buffer = (struct hv_ring_buffer *) + vmap(pages_wraparound, page_cnt * 2 - 1, VM_MAP, +- pgprot_decrypted(PAGE_KERNEL)); ++ confidential ? PAGE_KERNEL : pgprot_decrypted(PAGE_KERNEL)); + + kfree(pages_wraparound); + if (!ring_info->ring_buffer) +-- +2.51.0 + diff --git a/queue-6.17/drivers-hv-free-msginfo-when-the-buffer-fails-to-dec.patch b/queue-6.17/drivers-hv-free-msginfo-when-the-buffer-fails-to-dec.patch new file mode 100644 index 0000000000..cf764ba933 --- /dev/null +++ b/queue-6.17/drivers-hv-free-msginfo-when-the-buffer-fails-to-dec.patch @@ -0,0 +1,86 @@ +From 21dda4b283c12e9f17f26add62621b9646e7c4b3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:34:16 -0700 +Subject: Drivers: hv: Free msginfo when the buffer fails to decrypt + +From: Roman Kisel + +[ Upstream commit 510164539f16062e842a9de762616b5008616fa1 ] + +The early failure path in __vmbus_establish_gpadl() doesn't deallocate +msginfo if the buffer fails to decrypt. + +Fix the leak by breaking out the cleanup code into a separate function +and calling it where required. + +Fixes: d4dccf353db80 ("Drivers: hv: vmbus: Mark vmbus ring buffer visible to host in Isolation VM") +Reported-by: Michael Kelley +Closes: https://lore.kernel.org/linux-hyperv/SN6PR02MB41573796F9787F67E0E97049D472A@SN6PR02MB4157.namprd02.prod.outlook.com +Signed-off-by: Roman Kisel +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/channel.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/drivers/hv/channel.c b/drivers/hv/channel.c +index 1621b95263a5b..70270202209b6 100644 +--- a/drivers/hv/channel.c ++++ b/drivers/hv/channel.c +@@ -410,6 +410,21 @@ static int create_gpadl_header(enum hv_gpadl_type type, void *kbuffer, + return 0; + } + ++static void vmbus_free_channel_msginfo(struct vmbus_channel_msginfo *msginfo) ++{ ++ struct vmbus_channel_msginfo *submsginfo, *tmp; ++ ++ if (!msginfo) ++ return; ++ ++ list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist, ++ msglistentry) { ++ kfree(submsginfo); ++ } ++ ++ kfree(msginfo); ++} ++ + /* + * __vmbus_establish_gpadl - Establish a GPADL for a buffer or ringbuffer + * +@@ -429,7 +444,7 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, + struct vmbus_channel_gpadl_header *gpadlmsg; + struct vmbus_channel_gpadl_body *gpadl_body; + struct vmbus_channel_msginfo *msginfo = NULL; +- struct vmbus_channel_msginfo *submsginfo, *tmp; ++ struct vmbus_channel_msginfo *submsginfo; + struct list_head *curr; + u32 next_gpadl_handle; + unsigned long flags; +@@ -459,6 +474,7 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, + dev_warn(&channel->device_obj->device, + "Failed to set host visibility for new GPADL %d.\n", + ret); ++ vmbus_free_channel_msginfo(msginfo); + return ret; + } + } +@@ -535,12 +551,8 @@ static int __vmbus_establish_gpadl(struct vmbus_channel *channel, + spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); + list_del(&msginfo->msglistentry); + spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); +- list_for_each_entry_safe(submsginfo, tmp, &msginfo->submsglist, +- msglistentry) { +- kfree(submsginfo); +- } + +- kfree(msginfo); ++ vmbus_free_channel_msginfo(msginfo); + + if (ret) { + /* +-- +2.51.0 + diff --git a/queue-6.17/drivers-hv-vmbus-protocol-version-6.0.patch b/queue-6.17/drivers-hv-vmbus-protocol-version-6.0.patch new file mode 100644 index 0000000000..ae36a9b437 --- /dev/null +++ b/queue-6.17/drivers-hv-vmbus-protocol-version-6.0.patch @@ -0,0 +1,193 @@ +From 3e405c5c587eb43d8daec137bc7efff2027d38a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:34:04 -0700 +Subject: Drivers: hv: VMBus protocol version 6.0 + +From: Roman Kisel + +[ Upstream commit 6802d8af47d1dccd9a74a1f708fb9129244ef843 ] + +The confidential VMBus is supported starting from the protocol +version 6.0 onwards. + +Provide the required definitions. No functional changes. + +Signed-off-by: Roman Kisel +Reviewed-by: Alok Tiwari +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Stable-dep-of: 510164539f16 ("Drivers: hv: Free msginfo when the buffer fails to decrypt") +Signed-off-by: Sasha Levin +--- + drivers/hv/hyperv_vmbus.h | 2 ++ + drivers/hv/vmbus_drv.c | 12 +++++++ + include/hyperv/hvgdk_mini.h | 1 + + include/linux/hyperv.h | 69 +++++++++++++++++++++++++++---------- + 4 files changed, 65 insertions(+), 19 deletions(-) + +diff --git a/drivers/hv/hyperv_vmbus.h b/drivers/hv/hyperv_vmbus.h +index 0b450e53161e5..4a01797d48513 100644 +--- a/drivers/hv/hyperv_vmbus.h ++++ b/drivers/hv/hyperv_vmbus.h +@@ -333,6 +333,8 @@ extern const struct vmbus_channel_message_table_entry + + /* General vmbus interface */ + ++bool vmbus_is_confidential(void); ++ + struct hv_device *vmbus_device_create(const guid_t *type, + const guid_t *instance, + struct vmbus_channel *channel); +diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c +index 2ed5a1e89d694..c2f913b9aad58 100644 +--- a/drivers/hv/vmbus_drv.c ++++ b/drivers/hv/vmbus_drv.c +@@ -56,6 +56,18 @@ static long __percpu *vmbus_evt; + int vmbus_irq; + int vmbus_interrupt; + ++/* ++ * If the Confidential VMBus is used, the data on the "wire" is not ++ * visible to either the host or the hypervisor. ++ */ ++static bool is_confidential; ++ ++bool vmbus_is_confidential(void) ++{ ++ return is_confidential; ++} ++EXPORT_SYMBOL_GPL(vmbus_is_confidential); ++ + /* + * The panic notifier below is responsible solely for unloading the + * vmbus connection, which is necessary in a panic event. +diff --git a/include/hyperv/hvgdk_mini.h b/include/hyperv/hvgdk_mini.h +index 1be7f6a023046..981a687bdc7eb 100644 +--- a/include/hyperv/hvgdk_mini.h ++++ b/include/hyperv/hvgdk_mini.h +@@ -260,6 +260,7 @@ union hv_hypervisor_version_info { + #define HYPERV_CPUID_VIRT_STACK_PROPERTIES 0x40000082 + /* Support for the extended IOAPIC RTE format */ + #define HYPERV_VS_PROPERTIES_EAX_EXTENDED_IOAPIC_RTE BIT(2) ++#define HYPERV_VS_PROPERTIES_EAX_CONFIDENTIAL_VMBUS_AVAILABLE BIT(3) + + #define HYPERV_HYPERVISOR_PRESENT_BIT 0x80000000 + #define HYPERV_CPUID_MIN 0x40000005 +diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h +index a59c5c3e95fb8..a1820fabbfc0c 100644 +--- a/include/linux/hyperv.h ++++ b/include/linux/hyperv.h +@@ -265,16 +265,18 @@ static inline u32 hv_get_avail_to_write_percent( + * Linux kernel. + */ + +-#define VERSION_WS2008 ((0 << 16) | (13)) +-#define VERSION_WIN7 ((1 << 16) | (1)) +-#define VERSION_WIN8 ((2 << 16) | (4)) +-#define VERSION_WIN8_1 ((3 << 16) | (0)) +-#define VERSION_WIN10 ((4 << 16) | (0)) +-#define VERSION_WIN10_V4_1 ((4 << 16) | (1)) +-#define VERSION_WIN10_V5 ((5 << 16) | (0)) +-#define VERSION_WIN10_V5_1 ((5 << 16) | (1)) +-#define VERSION_WIN10_V5_2 ((5 << 16) | (2)) +-#define VERSION_WIN10_V5_3 ((5 << 16) | (3)) ++#define VMBUS_MAKE_VERSION(MAJ, MIN) ((((u32)MAJ) << 16) | (MIN)) ++#define VERSION_WS2008 VMBUS_MAKE_VERSION(0, 13) ++#define VERSION_WIN7 VMBUS_MAKE_VERSION(1, 1) ++#define VERSION_WIN8 VMBUS_MAKE_VERSION(2, 4) ++#define VERSION_WIN8_1 VMBUS_MAKE_VERSION(3, 0) ++#define VERSION_WIN10 VMBUS_MAKE_VERSION(4, 0) ++#define VERSION_WIN10_V4_1 VMBUS_MAKE_VERSION(4, 1) ++#define VERSION_WIN10_V5 VMBUS_MAKE_VERSION(5, 0) ++#define VERSION_WIN10_V5_1 VMBUS_MAKE_VERSION(5, 1) ++#define VERSION_WIN10_V5_2 VMBUS_MAKE_VERSION(5, 2) ++#define VERSION_WIN10_V5_3 VMBUS_MAKE_VERSION(5, 3) ++#define VERSION_WIN10_V6_0 VMBUS_MAKE_VERSION(6, 0) + + /* Make maximum size of pipe payload of 16K */ + #define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384) +@@ -335,14 +337,22 @@ struct vmbus_channel_offer { + } __packed; + + /* Server Flags */ +-#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 1 +-#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES 2 +-#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS 4 +-#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x10 +-#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x100 +-#define VMBUS_CHANNEL_PARENT_OFFER 0x200 +-#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x400 +-#define VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER 0x2000 ++#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE 0x0001 ++/* ++ * This flag indicates that the channel is offered by the paravisor, and must ++ * use encrypted memory for the channel ring buffer. ++ */ ++#define VMBUS_CHANNEL_CONFIDENTIAL_RING_BUFFER 0x0002 ++/* ++ * This flag indicates that the channel is offered by the paravisor, and must ++ * use encrypted memory for GPA direct packets and additional GPADLs. ++ */ ++#define VMBUS_CHANNEL_CONFIDENTIAL_EXTERNAL_MEMORY 0x0004 ++#define VMBUS_CHANNEL_NAMED_PIPE_MODE 0x0010 ++#define VMBUS_CHANNEL_LOOPBACK_OFFER 0x0100 ++#define VMBUS_CHANNEL_PARENT_OFFER 0x0200 ++#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION 0x0400 ++#define VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER 0x2000 + + struct vmpacket_descriptor { + u16 type; +@@ -621,6 +631,12 @@ struct vmbus_channel_relid_released { + u32 child_relid; + } __packed; + ++/* ++ * Used by the paravisor only, means that the encrypted ring buffers and ++ * the encrypted external memory are supported ++ */ ++#define VMBUS_FEATURE_FLAG_CONFIDENTIAL_CHANNELS 0x10 ++ + struct vmbus_channel_initiate_contact { + struct vmbus_channel_message_header header; + u32 vmbus_version_requested; +@@ -630,7 +646,8 @@ struct vmbus_channel_initiate_contact { + struct { + u8 msg_sint; + u8 msg_vtl; +- u8 reserved[6]; ++ u8 reserved[2]; ++ u32 feature_flags; /* VMBus version 6.0 */ + }; + }; + u64 monitor_page1; +@@ -1008,6 +1025,10 @@ struct vmbus_channel { + + /* boolean to control visibility of sysfs for ring buffer */ + bool ring_sysfs_visible; ++ /* The ring buffer is encrypted */ ++ bool co_ring_buffer; ++ /* The external memory is encrypted */ ++ bool co_external_memory; + }; + + #define lock_requestor(channel, flags) \ +@@ -1032,6 +1053,16 @@ u64 vmbus_request_addr_match(struct vmbus_channel *channel, u64 trans_id, + u64 rqst_addr); + u64 vmbus_request_addr(struct vmbus_channel *channel, u64 trans_id); + ++static inline bool is_co_ring_buffer(const struct vmbus_channel_offer_channel *o) ++{ ++ return !!(o->offer.chn_flags & VMBUS_CHANNEL_CONFIDENTIAL_RING_BUFFER); ++} ++ ++static inline bool is_co_external_memory(const struct vmbus_channel_offer_channel *o) ++{ ++ return !!(o->offer.chn_flags & VMBUS_CHANNEL_CONFIDENTIAL_EXTERNAL_MEMORY); ++} ++ + static inline bool is_hvsock_offer(const struct vmbus_channel_offer_channel *o) + { + return !!(o->offer.chn_flags & VMBUS_CHANNEL_TLNPI_PROVIDER_OFFER); +-- +2.51.0 + diff --git a/queue-6.17/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-6.17/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..ca42e5ff0f --- /dev/null +++ b/queue-6.17/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From beb15d324e2315763c8d930f2d00ed8b3cc88270 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 04eb647acc4e1..550a9f1d03f82 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-6.17/drm-amdgpu-add-userq-object-va-track-helpers.patch b/queue-6.17/drm-amdgpu-add-userq-object-va-track-helpers.patch new file mode 100644 index 0000000000..b655402556 --- /dev/null +++ b/queue-6.17/drm-amdgpu-add-userq-object-va-track-helpers.patch @@ -0,0 +1,207 @@ +From 1c20f24b3f50bcb4931c3608ac22b566f4dde82b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 13:52:13 +0800 +Subject: drm/amdgpu: add userq object va track helpers + +From: Prike Liang + +[ Upstream commit 5cfa33fabf01f2cc0af6b1feed6e65cb81806a37 ] + +Add the userq object virtual address list_add() helpers +for tracking the userq obj va address usage. + +Signed-off-by: Prike Liang +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Stable-dep-of: a0559012a18a ("drm/amdgpu/userq: fix SDMA and compute validation") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 44 ++++++++++++++++------ + drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 12 ++++-- + drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 16 ++++---- + 4 files changed, 52 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +index c316920f34509..1e1ee4a0cd0d1 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +@@ -96,6 +96,7 @@ struct amdgpu_bo_va { + * if non-zero, cannot unmap from GPU because user queues may still access it + */ + unsigned int queue_refcount; ++ atomic_t userq_va_mapped; + }; + + struct amdgpu_bo { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +index a0fb13172e8b4..0b9269aaabde5 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +@@ -44,10 +44,29 @@ u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) + return userq_ip_mask; + } + +-int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, +- u64 expected_size) ++static int amdgpu_userq_buffer_va_list_add(struct amdgpu_usermode_queue *queue, ++ struct amdgpu_bo_va_mapping *va_map, u64 addr) ++{ ++ struct amdgpu_userq_va_cursor *va_cursor; ++ struct userq_va_list; ++ ++ va_cursor = kzalloc(sizeof(*va_cursor), GFP_KERNEL); ++ if (!va_cursor) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&va_cursor->list); ++ va_cursor->gpu_addr = addr; ++ atomic_set(&va_map->bo_va->userq_va_mapped, 1); ++ list_add(&va_cursor->list, &queue->userq_va_list); ++ ++ return 0; ++} ++ ++int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, ++ u64 addr, u64 expected_size) + { + struct amdgpu_bo_va_mapping *va_map; ++ struct amdgpu_vm *vm = queue->vm; + u64 user_addr; + u64 size; + int r = 0; +@@ -67,6 +86,7 @@ int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, + /* Only validate the userq whether resident in the VM mapping range */ + if (user_addr >= va_map->start && + va_map->last - user_addr + 1 >= size) { ++ amdgpu_userq_buffer_va_list_add(queue, va_map, user_addr); + amdgpu_bo_unreserve(vm->root.bo); + return 0; + } +@@ -142,6 +162,7 @@ amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr, + uq_funcs->mqd_destroy(uq_mgr, queue); + amdgpu_userq_fence_driver_free(queue); + idr_remove(&uq_mgr->userq_idr, queue_id); ++ list_del(&queue->userq_va_list); + kfree(queue); + } + +@@ -473,14 +494,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + goto unlock; + } + +- /* Validate the userq virtual address.*/ +- if (amdgpu_userq_input_va_validate(&fpriv->vm, args->in.queue_va, args->in.queue_size) || +- amdgpu_userq_input_va_validate(&fpriv->vm, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || +- amdgpu_userq_input_va_validate(&fpriv->vm, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { +- r = -EINVAL; +- kfree(queue); +- goto unlock; +- } ++ INIT_LIST_HEAD(&queue->userq_va_list); + queue->doorbell_handle = args->in.doorbell_handle; + queue->queue_type = args->in.ip_type; + queue->vm = &fpriv->vm; +@@ -491,6 +505,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + db_info.db_obj = &queue->db_obj; + db_info.doorbell_offset = args->in.doorbell_offset; + ++ /* Validate the userq virtual address.*/ ++ if (amdgpu_userq_input_va_validate(queue, args->in.queue_va, args->in.queue_size) || ++ amdgpu_userq_input_va_validate(queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || ++ amdgpu_userq_input_va_validate(queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { ++ r = -EINVAL; ++ kfree(queue); ++ goto unlock; ++ } ++ + /* Convert relative doorbell offset into absolute doorbell index */ + index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp); + if (index == (uint64_t)-EINVAL) { +@@ -516,7 +539,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + goto unlock; + } + +- + qid = idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ_COUNT, GFP_KERNEL); + if (qid < 0) { + drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n"); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +index 8603c31320f11..17ac12893ef9c 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +@@ -47,6 +47,11 @@ struct amdgpu_userq_obj { + struct amdgpu_bo *obj; + }; + ++struct amdgpu_userq_va_cursor { ++ u64 gpu_addr; ++ struct list_head list; ++}; ++ + struct amdgpu_usermode_queue { + int queue_type; + enum amdgpu_userq_state state; +@@ -66,6 +71,8 @@ struct amdgpu_usermode_queue { + u32 xcp_id; + int priority; + struct dentry *debugfs_queue; ++ ++ struct list_head userq_va_list; + }; + + struct amdgpu_userq_funcs { +@@ -132,7 +139,6 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev, + u32 idx); + int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, + u32 idx); +- +-int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, +- u64 expected_size); ++int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, ++ u64 addr, u64 expected_size); + #endif +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +index ef54d211214f4..00dd5f37f4374 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +@@ -250,8 +250,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + goto free_mqd; + } + +- if (amdgpu_userq_input_va_validate(queue->vm, compute_mqd->eop_va, +- max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE))) ++ r = amdgpu_userq_input_va_validate(queue, compute_mqd->eop_va, ++ max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE)); ++ if (r) + goto free_mqd; + + userq_props->eop_gpu_addr = compute_mqd->eop_va; +@@ -282,8 +283,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + userq_props->tmz_queue = + mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; + +- if (amdgpu_userq_input_va_validate(queue->vm, mqd_gfx_v11->shadow_va, +- shadow_info.shadow_size)) ++ r = amdgpu_userq_input_va_validate(queue, mqd_gfx_v11->shadow_va, ++ shadow_info.shadow_size); ++ if (r) + goto free_mqd; + + kfree(mqd_gfx_v11); +@@ -302,9 +304,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + r = -ENOMEM; + goto free_mqd; + } +- +- if (amdgpu_userq_input_va_validate(queue->vm, mqd_sdma_v11->csa_va, +- shadow_info.csa_size)) ++ r = amdgpu_userq_input_va_validate(queue, mqd_sdma_v11->csa_va, ++ shadow_info.csa_size); ++ if (r) + goto free_mqd; + + userq_props->csa_addr = mqd_sdma_v11->csa_va; +-- +2.51.0 + diff --git a/queue-6.17/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch b/queue-6.17/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch new file mode 100644 index 0000000000..0e63fbe453 --- /dev/null +++ b/queue-6.17/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch @@ -0,0 +1,91 @@ +From b34e8050da01d15af8f229c97a33038738813252 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 15:21:02 -0400 +Subject: drm/amdgpu/userq: fix SDMA and compute validation + +From: Alex Deucher + +[ Upstream commit a0559012a18a5a6ad87516e982892765a403b8ab ] + +The CSA and EOP buffers have different alignement requirements. +Hardcode them for now as a bug fix. A proper query will be added in +a subsequent patch. + +v2: verify gfx shadow helper callback (Prike) + +Fixes: 9e46b8bb0539 ("drm/amdgpu: validate userq buffer virtual address and size") +Reviewed-by: Prike Liang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +index 00dd5f37f4374..1cd1fdec9cc97 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +@@ -206,7 +206,6 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_mqd *mqd_hw_default = &adev->mqds[queue->queue_type]; + struct drm_amdgpu_userq_in *mqd_user = args_in; + struct amdgpu_mqd_prop *userq_props; +- struct amdgpu_gfx_shadow_info shadow_info; + int r; + + /* Structure to initialize MQD for userqueue using generic MQD init function */ +@@ -232,8 +231,6 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + userq_props->doorbell_index = queue->doorbell_index; + userq_props->fence_address = queue->fence_drv->gpu_addr; + +- if (adev->gfx.funcs->get_gfx_shadow_info) +- adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow_info, true); + if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { + struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; + +@@ -251,7 +248,7 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + } + + r = amdgpu_userq_input_va_validate(queue, compute_mqd->eop_va, +- max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE)); ++ 2048); + if (r) + goto free_mqd; + +@@ -264,6 +261,14 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + kfree(compute_mqd); + } else if (queue->queue_type == AMDGPU_HW_IP_GFX) { + struct drm_amdgpu_userq_mqd_gfx11 *mqd_gfx_v11; ++ struct amdgpu_gfx_shadow_info shadow_info; ++ ++ if (adev->gfx.funcs->get_gfx_shadow_info) { ++ adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow_info, true); ++ } else { ++ r = -EINVAL; ++ goto free_mqd; ++ } + + if (mqd_user->mqd_size != sizeof(*mqd_gfx_v11) || !mqd_user->mqd) { + DRM_ERROR("Invalid GFX MQD\n"); +@@ -287,6 +292,10 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + shadow_info.shadow_size); + if (r) + goto free_mqd; ++ r = amdgpu_userq_input_va_validate(queue, mqd_gfx_v11->csa_va, ++ shadow_info.csa_size); ++ if (r) ++ goto free_mqd; + + kfree(mqd_gfx_v11); + } else if (queue->queue_type == AMDGPU_HW_IP_DMA) { +@@ -305,7 +314,7 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + goto free_mqd; + } + r = amdgpu_userq_input_va_validate(queue, mqd_sdma_v11->csa_va, +- shadow_info.csa_size); ++ 32); + if (r) + goto free_mqd; + +-- +2.51.0 + diff --git a/queue-6.17/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch b/queue-6.17/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch new file mode 100644 index 0000000000..bfd4c3f0d3 --- /dev/null +++ b/queue-6.17/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch @@ -0,0 +1,91 @@ +From 56e0515b668af807a4711bb577b63df004cf4150 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Oct 2024 15:19:42 +0530 +Subject: drm: atmel-hlcdc: fix atmel_xlcdc_plane_setup_scaler() + +From: Cyrille Pitchen + +[ Upstream commit a312acdcec57b3955fbf1f3057c13a6d38e4aa2a ] + +On SoCs, like the SAM9X75, which embed the XLCDC ip, the registers that +configure the unified scaling engine were not filled with proper values. + +Indeed, for YCbCr formats, the VXSCFACT bitfield of the HEOCFG25 +register and the HXSCFACT bitfield of the HEOCFG27 register were +incorrect. + +For 4:2:0 formats, both vertical and horizontal factors for +chroma chanels should be divided by 2 from the factors for the luma +channel. Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VSXCFACT = VFACTOR / 2 +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +However, for 4:2:2 formats, only the horizontal factor for chroma +chanels should be divided by 2 from the factor for the luma channel; +the vertical factor is the same for all the luma and chroma channels. +Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VXSCFACT = VFACTOR +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +Fixes: d498771b0b83 ("drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops") +Signed-off-by: Cyrille Pitchen +Reviewed-by: Dmitry Baryshkov +Acked-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20241014094942.325211-1-manikandan.m@microchip.com +Signed-off-by: Manikandan Muralidharan +Signed-off-by: Sasha Levin +--- + .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 27 ++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +index 4a7ba0918eca1..3787db014501e 100644 +--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c ++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +@@ -365,13 +365,34 @@ void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, + xfactor); + + /* +- * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration +- * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half ++ * With YCbCr 4:2:0 window resampling, configuration register ++ * LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT values are half + * the value of yfactor and xfactor. ++ * ++ * On the other hand, with YCbCr 4:2:2 window resampling, only the ++ * configuration register LCDC_HEOCFG27.HXSCFACT value is half the value ++ * of the xfactor; the value of LCDC_HEOCFG25.VXSCFACT is yfactor (no ++ * division by 2). + */ +- if (state->base.fb->format->format == DRM_FORMAT_YUV420) { ++ switch (state->base.fb->format->format) { ++ /* YCbCr 4:2:2 */ ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_UYVY: ++ case DRM_FORMAT_YVYU: ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_YUV422: ++ case DRM_FORMAT_NV61: ++ xfactor /= 2; ++ break; ++ ++ /* YCbCr 4:2:0 */ ++ case DRM_FORMAT_YUV420: ++ case DRM_FORMAT_NV21: + yfactor /= 2; + xfactor /= 2; ++ break; ++ default: ++ break; + } + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2, +-- +2.51.0 + diff --git a/queue-6.17/drm-imagination-fix-reference-to-devm_platform_get_a.patch b/queue-6.17/drm-imagination-fix-reference-to-devm_platform_get_a.patch new file mode 100644 index 0000000000..a268e92a23 --- /dev/null +++ b/queue-6.17/drm-imagination-fix-reference-to-devm_platform_get_a.patch @@ -0,0 +1,40 @@ +From ea83b8bc91b30577b3f5498e2d8bfa0c6db013eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 16:00:28 +0100 +Subject: drm/imagination: Fix reference to + devm_platform_get_and_ioremap_resource() + +From: Geert Uytterhoeven + +[ Upstream commit f1aa93005d0d6fb3293ca9c3eb08d1d1557117bf ] + +The call to devm_platform_ioremap_resource() was replaced by a call to +devm_platform_get_and_ioremap_resource(), but the comment referring to +the function's possible returned error codes was not updated. + +Fixes: 927f3e0253c11276 ("drm/imagination: Implement MIPS firmware processor and MMU support") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Matt Coster +Link: https://patch.msgid.link/2266514318480d17f52c7e5e67578dae6827914e.1761745586.git.geert+renesas@glider.be +Signed-off-by: Matt Coster +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/imagination/pvr_device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c +index 8b9ba4983c4cb..f9271efbd74aa 100644 +--- a/drivers/gpu/drm/imagination/pvr_device.c ++++ b/drivers/gpu/drm/imagination/pvr_device.c +@@ -47,7 +47,7 @@ + * + * Return: + * * 0 on success, or +- * * Any error returned by devm_platform_ioremap_resource(). ++ * * Any error returned by devm_platform_get_and_ioremap_resource(). + */ + static int + pvr_device_reg_init(struct pvr_device *pvr_dev) +-- +2.51.0 + diff --git a/queue-6.17/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-6.17/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..d9bf900772 --- /dev/null +++ b/queue-6.17/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From f4780eaed07cdba179c76edf3f4fe12b6f15fc8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 10d60d2c2a568..6d7bf4afa78d3 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch b/queue-6.17/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch new file mode 100644 index 0000000000..79b8beb7d2 --- /dev/null +++ b/queue-6.17/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch @@ -0,0 +1,42 @@ +From 4ad467d90f209067fa92aac7bf5730ddfd01eb38 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:40:50 +0200 +Subject: drm/msm/a2xx: stop over-complaining about the legacy firmware + +From: Dmitry Baryshkov + +[ Upstream commit a3a22373fce576560757f5616eb48dbf85891d9c ] + +If the rootfs have a legacy A200 firmware, currently the driver will +complain each time the hw is reinited (which can happen a lot). E.g. +with GL testsuite the hw is reinited after each test, spamming the +console. + +Make sure that the message is printed only once: when we detect the +firmware that doesn't support protection. + +Fixes: 302295070d3c ("drm/msm/a2xx: support loading legacy (iMX) firmware") +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/688098/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +index ec38db45d8a36..963c0f669ee50 100644 +--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +@@ -234,7 +234,7 @@ static int a2xx_hw_init(struct msm_gpu *gpu) + * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225). + * Older firmware files, which lack protection support, have 0 instead. + */ +- if (ptr[1] == 0) { ++ if (ptr[1] == 0 && !a2xx_gpu->protection_disabled) { + dev_warn(gpu->dev->dev, + "Legacy firmware detected, disabling protection support\n"); + a2xx_gpu->protection_disabled = true; +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-a6xx-fix-the-gemnoc-workaround.patch b/queue-6.17/drm-msm-a6xx-fix-the-gemnoc-workaround.patch new file mode 100644 index 0000000000..68afaa1b93 --- /dev/null +++ b/queue-6.17/drm-msm-a6xx-fix-the-gemnoc-workaround.patch @@ -0,0 +1,55 @@ +From f4fe0bec176cc922509eb58528effbb2f6244def Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:30 +0530 +Subject: drm/msm/a6xx: Fix the gemnoc workaround + +From: Akhil P Oommen + +[ Upstream commit ff7a6de043fce21ea5891311746b16121b385c59 ] + +Correct the register offset and enable this workaround for all A7x +and newer GPUs to match the recommendation. Also, downstream does this +w/a after moving the fence to allow mode. So do the same. + +Fixes: dbfbb376b50c ("drm/msm/a6xx: Add A621 support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688997/ +Message-ID: <20251118-kaana-gpu-support-v4-3-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index ee82489025c3c..bc7e111c46f96 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -471,8 +471,9 @@ static void a6xx_gemnoc_workaround(struct a6xx_gmu *gmu) + * in the power down sequence not being fully executed. That in turn can + * prevent CX_GDSC from collapsing. Assert Qactive to avoid this. + */ +- if (adreno_is_a621(adreno_gpu) || adreno_is_7c3(adreno_gpu)) +- gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, BIT(0)); ++ if (adreno_is_a7xx(adreno_gpu) || (adreno_is_a621(adreno_gpu) || ++ adreno_is_7c3(adreno_gpu))) ++ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, BIT(0)); + } + + /* Let the GMU know that we are about to go into slumber */ +@@ -508,10 +509,9 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) + } + + out: +- a6xx_gemnoc_workaround(gmu); +- + /* Put fence into allow mode */ + gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); ++ a6xx_gemnoc_workaround(gmu); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch b/queue-6.17/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch new file mode 100644 index 0000000000..0c7200cda5 --- /dev/null +++ b/queue-6.17/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch @@ -0,0 +1,56 @@ +From 1fe5bbdb4b5717a6d130bea76d56148390e17dfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:29 +0530 +Subject: drm/msm/a6xx: Flush LRZ cache before PT switch + +From: Akhil P Oommen + +[ Upstream commit 180349b8407f3b268b2ceac0e590b8199e043081 ] + +As per the recommendation, A7x and newer GPUs should flush the LRZ cache +before switching the pagetable. Update a6xx_set_pagetable() to do this. +While we are at it, sync both BV and BR before issuing a +CP_RESET_CONTEXT_STATE command, to match the downstream sequence. + +Fixes: af66706accdf ("drm/msm/a6xx: Add skeleton A7xx support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688995/ +Message-ID: <20251118-kaana-gpu-support-v4-2-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index 1e363af319488..f8939f0fad4f2 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -224,7 +224,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + OUT_RING(ring, submit->seqno - 1); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BOTH); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); + + /* Reset state used to synchronize BR and BV */ + OUT_PKT7(ring, CP_RESET_CONTEXT_STATE, 1); +@@ -235,7 +235,13 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + CP_RESET_CONTEXT_STATE_0_RESET_GLOBAL_LOCAL_TS); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BR); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); ++ ++ OUT_PKT7(ring, CP_EVENT_WRITE, 1); ++ OUT_RING(ring, LRZ_FLUSH); ++ ++ OUT_PKT7(ring, CP_THREAD_CONTROL, 1); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); + } + + if (!sysprof) { +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch b/queue-6.17/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch new file mode 100644 index 0000000000..70199035ea --- /dev/null +++ b/queue-6.17/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch @@ -0,0 +1,92 @@ +From bde6b011090f09624d2566a59c964fc253053ae9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:39 +0530 +Subject: drm/msm/a6xx: Improve MX rail fallback in RPMH vote init + +From: Akhil P Oommen + +[ Upstream commit ca04ce7a2f22652fdf6489fa7e02e7d2c08698f4 ] + +Current logic assumes that the voltage corners in both MxG and MxA are +always same. This is not true for recent targets. So, rework the rpmh init +sequence to probe and calculate the votes with the respective rails, ie, +GX rails should use MxG as secondary rail and Cx rail should use MxA as +the secondary rail. + +Fixes: d6225e0cd096 ("drm/msm/adreno: Add support for X185 GPU") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/689014/ +Message-ID: <20251118-kaana-gpu-support-v4-12-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index bc7e111c46f96..4f6e68c86b586 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -1459,13 +1459,14 @@ static unsigned int a6xx_gmu_get_arc_level(struct device *dev, + } + + static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, +- unsigned long *freqs, int freqs_count, const char *id) ++ unsigned long *freqs, int freqs_count, ++ const char *pri_id, const char *sec_id) + { + int i, j; + const u16 *pri, *sec; + size_t pri_count, sec_count; + +- pri = cmd_db_read_aux_data(id, &pri_count); ++ pri = cmd_db_read_aux_data(pri_id, &pri_count); + if (IS_ERR(pri)) + return PTR_ERR(pri); + /* +@@ -1476,13 +1477,7 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, + if (!pri_count) + return -EINVAL; + +- /* +- * Some targets have a separate gfx mxc rail. So try to read that first and then fall back +- * to regular mx rail if it is missing +- */ +- sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); +- if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER)) +- sec = cmd_db_read_aux_data("mx.lvl", &sec_count); ++ sec = cmd_db_read_aux_data(sec_id, &sec_count); + if (IS_ERR(sec)) + return PTR_ERR(sec); + +@@ -1550,15 +1545,24 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu) + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + const struct a6xx_info *info = adreno_gpu->info->a6xx; + struct msm_gpu *gpu = &adreno_gpu->base; ++ const char *sec_id; ++ const u16 *gmxc; + int ret; + ++ gmxc = cmd_db_read_aux_data("gmxc.lvl", NULL); ++ if (gmxc == ERR_PTR(-EPROBE_DEFER)) ++ return -EPROBE_DEFER; ++ ++ /* If GMxC is present, prefer that as secondary rail for GX votes */ ++ sec_id = IS_ERR_OR_NULL(gmxc) ? "mx.lvl" : "gmxc.lvl"; ++ + /* Build the GX votes */ + ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes, +- gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl"); ++ gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl", sec_id); + + /* Build the CX votes */ + ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes, +- gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl"); ++ gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl", "mx.lvl"); + + /* Build the interconnect votes */ + if (info->bcms && gmu->nr_gpu_bws > 1) +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch b/queue-6.17/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch new file mode 100644 index 0000000000..3cca2960a3 --- /dev/null +++ b/queue-6.17/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch @@ -0,0 +1,45 @@ +From 2c5bf364e7a0c6e30bf413bcc182e44e24580e63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:35:17 +0200 +Subject: drm/msm/dpu: drop dpu_hw_dsc_destroy() prototype + +From: Dmitry Baryshkov + +[ Upstream commit d9792823d18ff9895eaf5769a29a54804f24bc25 ] + +The commit a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for +HW blocks") dropped all dpu_hw_foo_destroy() functions, but the +prototype for dpu_hw_dsc_destroy() was omitted. Drop it now to clean up +the header. + +Fixes: a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for HW blocks") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Reviewed-by: Jessica Zhang +Patchwork: https://patchwork.freedesktop.org/patch/683697/ +Link: https://lore.kernel.org/r/20251027-dpu-drop-dsc-destroy-v1-1-968128de4bf6@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +index b7013c9822d23..cc7cc6f6f7cda 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +@@ -71,12 +71,6 @@ struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, + const struct dpu_dsc_cfg *cfg, + void __iomem *addr); + +-/** +- * dpu_hw_dsc_destroy - destroys dsc driver context +- * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init +- */ +-void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc); +- + static inline struct dpu_hw_dsc *to_dpu_hw_dsc(struct dpu_hw_blk *hw) + { + return container_of(hw, struct dpu_hw_dsc, base); +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch b/queue-6.17/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch new file mode 100644 index 0000000000..b11bc147ae --- /dev/null +++ b/queue-6.17/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch @@ -0,0 +1,60 @@ +From 2e43134e4e2852863ec1afa7cc41c70023977c97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 01:19:47 +0800 +Subject: drm/msm: fix missing NULL check after kcalloc in crashstate_get_bos() + +From: Huiwen He + +[ Upstream commit 3065e6a4d3594b42dae6176b3e2c0c3563cf94b8 ] + +The crashstate_get_bos() function allocates memory for `state->bos` +using kcalloc(), but the vmbind path does not check for allocation +failure before dereferencing it in the following drm_gpuvm_for_each_va() +loop. This could lead to a NULL pointer dereference if memory allocation +fails. + +Fix this by wrapping the drm_gpuvm_for_each_va() loop with a NULL check +on state->bos, similar to the safety check in the non-vmbind path. + +Fixes: af9aa6f316b3d ("drm/msm: Crashdump support for sparse") +Signed-off-by: Huiwen He +Patchwork: https://patchwork.freedesktop.org/patch/687556/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gpu.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c +index 8f933c1fe4bfa..d5f8df3110cef 100644 +--- a/drivers/gpu/drm/msm/msm_gpu.c ++++ b/drivers/gpu/drm/msm/msm_gpu.c +@@ -287,16 +287,17 @@ static void crashstate_get_bos(struct msm_gpu_state *state, struct msm_gem_submi + + state->bos = kcalloc(cnt, sizeof(struct msm_gpu_state_bo), GFP_KERNEL); + +- drm_gpuvm_for_each_va (vma, submit->vm) { +- bool dump = rd_full || (vma->flags & MSM_VMA_DUMP); ++ if (state->bos) ++ drm_gpuvm_for_each_va(vma, submit->vm) { ++ bool dump = rd_full || (vma->flags & MSM_VMA_DUMP); + +- /* Skip MAP_NULL/PRR VMAs: */ +- if (!vma->gem.obj) +- continue; ++ /* Skip MAP_NULL/PRR VMAs: */ ++ if (!vma->gem.obj) ++ continue; + +- msm_gpu_crashstate_get_bo(state, vma->gem.obj, vma->va.addr, +- dump, vma->gem.offset, vma->va.range); +- } ++ msm_gpu_crashstate_get_bo(state, vma->gem.obj, vma->va.addr, ++ dump, vma->gem.offset, vma->va.range); ++ } + + drm_exec_fini(&exec); + } else { +-- +2.51.0 + diff --git a/queue-6.17/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch b/queue-6.17/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch new file mode 100644 index 0000000000..be6ba0e007 --- /dev/null +++ b/queue-6.17/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch @@ -0,0 +1,44 @@ +From 6acddd6bec9ba323920b6f615be5eaa6559c1a9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 01:04:11 +0800 +Subject: drm/msm: Fix NULL pointer dereference in crashstate_get_vm_logs() + +From: Huiwen He + +[ Upstream commit 3099e0247e3217e1b39c1c61766e06ec3d13835f ] + +crashstate_get_vm_logs() did not check the return value of +kmalloc_array(). In low-memory situations, kmalloc_array() may return +NULL, leading to a NULL pointer dereference when the function later +accesses state->vm_logs. + +Fix this by checking the return value of kmalloc_array() and setting +state->nr_vm_logs to 0 if allocation fails. + +Fixes: 9edc52967cc7 ("drm/msm: Add VM logging for VM_BIND updates") +Signed-off-by: Huiwen He +Patchwork: https://patchwork.freedesktop.org/patch/687555/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gpu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c +index 26c5ce897cbbd..8f933c1fe4bfa 100644 +--- a/drivers/gpu/drm/msm/msm_gpu.c ++++ b/drivers/gpu/drm/msm/msm_gpu.c +@@ -348,6 +348,10 @@ static void crashstate_get_vm_logs(struct msm_gpu_state *state, struct msm_gem_v + + state->vm_logs = kmalloc_array( + state->nr_vm_logs, sizeof(vm->log[0]), GFP_KERNEL); ++ if (!state->vm_logs) { ++ state->nr_vm_logs = 0; ++ } ++ + for (int i = 0; i < state->nr_vm_logs; i++) { + int idx = (i + first) & vm_log_mask; + +-- +2.51.0 + diff --git a/queue-6.17/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch b/queue-6.17/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch new file mode 100644 index 0000000000..d74d424b62 --- /dev/null +++ b/queue-6.17/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch @@ -0,0 +1,55 @@ +From 8f2e3e8188b2c7282df0626b10e56a61b779c2b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 17:03:22 -0600 +Subject: drm/nouveau: restrict the flush page to a 32-bit address + +From: Timur Tabi + +[ Upstream commit 04d98b3452331fa53ec3b698b66273af6ef73288 ] + +The flush page DMA address is stored in a special register that is not +associated with the GPU's standard DMA range. For example, on Turing, +the GPU's MMU can handle 47-bit addresses, but the flush page address +register is limited to 40 bits. + +At the point during device initialization when the flush page is +allocated, the DMA mask is still at its default of 32 bits. So even +though it's unlikely that the flush page could exist above a 40-bit +address, the dma_map_page() call could fail, e.g. if IOMMU is disabled +and the address is above 32 bits. The simplest way to achieve all +constraints is to allocate the page in the DMA32 zone. Since the flush +page is literally just a page, this is an acceptable limitation. The +alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper +and later) bits, but that could have unforseen side effects. + +In situations where the flush page is allocated above 32 bits and IOMMU +is disabled, you will get an error like this: + +nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0). + +Fixes: 5728d064190e ("drm/nouveau/fb: handle sysmem flush page from common code") +Signed-off-by: Timur Tabi +Reviewed-by: Lyude Paul +Signed-off-by: Lyude Paul +Link: https://patch.msgid.link/20251113230323.1271726-1-ttabi@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +index 8a286a9349ac6..7ce1b65e2c1c2 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +@@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, + mutex_init(&fb->tags.mutex); + + if (func->sysmem.flush_page_init) { +- fb->sysmem.flush_page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + if (!fb->sysmem.flush_page) + return -ENOMEM; + +-- +2.51.0 + diff --git a/queue-6.17/drm-nova-select-nova_core.patch b/queue-6.17/drm-nova-select-nova_core.patch new file mode 100644 index 0000000000..e30f6b9d69 --- /dev/null +++ b/queue-6.17/drm-nova-select-nova_core.patch @@ -0,0 +1,37 @@ +From 7e28616dd12c10ea82a95dd9d16637c34de4f6ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 12:00:53 +0100 +Subject: drm: nova: select NOVA_CORE + +From: Danilo Krummrich + +[ Upstream commit 97ad568cd6a58804129ba071f3258b5c4782fb0d ] + +The nova-drm driver does not provide any value without nova-core being +selected as well, hence select NOVA_CORE. + +Fixes: cdeaeb9dd762 ("drm: nova-drm: add initial driver skeleton") +Reviewed-by: Alexandre Courbot +Reviewed-by: John Hubbard +Link: https://patch.msgid.link/20251028110058.340320-2-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nova/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/nova/Kconfig b/drivers/gpu/drm/nova/Kconfig +index cca6a3fea879b..bd1df08791911 100644 +--- a/drivers/gpu/drm/nova/Kconfig ++++ b/drivers/gpu/drm/nova/Kconfig +@@ -4,6 +4,7 @@ config DRM_NOVA + depends on PCI + depends on RUST + select AUXILIARY_BUS ++ select NOVA_CORE + default n + help + Choose this if you want to build the Nova DRM driver for Nvidia +-- +2.51.0 + diff --git a/queue-6.17/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-6.17/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..5eef4dc96d --- /dev/null +++ b/queue-6.17/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From c1869a857566c708cbe4feaf829ddd7617bd3791 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 5491d601681cf..66c30db3b73a7 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -192,7 +192,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + +-- +2.51.0 + diff --git a/queue-6.17/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch b/queue-6.17/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch new file mode 100644 index 0000000000..47910ffeca --- /dev/null +++ b/queue-6.17/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch @@ -0,0 +1,42 @@ +From 97f7eda31523db9f3bc13dc53217f6ba23326c20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:56 +0200 +Subject: drm/panel: visionox-rm69299: Fix clock frequency for SHIFT6mq +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit d298062312724606855294503acebc7ee55ffbca ] + +Make the clock frequency match what the sdm845 downstream kernel +uses. Otherwise the panel stays black. + +Fixes: 783334f366b18 ("drm/panel: visionox-rm69299: support the variant found in the SHIFT6mq") +Signed-off-by: Guido Günther +Reviewed-by: Neil Armstrong +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-1-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 909c280eab1fb..5491d601681cf 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -247,7 +247,7 @@ static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = { + }; + + static const struct drm_display_mode visionox_rm69299_1080x2160_60hz = { +- .clock = 158695, ++ .clock = (2160 + 8 + 4 + 4) * (1080 + 26 + 2 + 36) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 26, + .hsync_end = 1080 + 26 + 2, +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch b/queue-6.17/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch new file mode 100644 index 0000000000..eb97739cfb --- /dev/null +++ b/queue-6.17/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch @@ -0,0 +1,64 @@ +From 8a5d7255b69ba46c0e810ec7a895e1403cd379d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 17:21:18 +0000 +Subject: drm/panthor: Avoid adding of kernel BOs to extobj list + +From: Akash Goel + +[ Upstream commit ce04ec03a9c2c4f3e60e26f21311b25d5a478208 ] + +The kernel BOs unnecessarily got added to the external objects list +of drm_gpuvm, when mapping to GPU, which would have resulted in few +extra CPU cycles being spent at the time of job submission as +drm_exec_until_all_locked() loop iterates over all external objects. + +Kernel BOs are private to a VM and so they share the dma_resv object of +the dummy GEM object created for a VM. Use of DRM_EXEC_IGNORE_DUPLICATES +flag ensured the recursive locking of the dummy GEM object was ignored. +Also no extra space got allocated to add fences to the dma_resv object +of dummy GEM object. So no other impact apart from few extra CPU cycles. + +This commit sets the pointer to dma_resv object of GEM object of +kernel BOs before they are mapped to GPU, to prevent them from +being added to external objects list. + +v2: Add R-bs and fixes tags + +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251120172118.2741724-1-akash.goel@arm.com +Signed-off-by: Boris Brezillon +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index 6830a89a7c10b..aca09bc449fc1 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -145,6 +145,9 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + bo = to_panthor_bo(&obj->base); + kbo->obj = &obj->base; + bo->flags = bo_flags; ++ bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); ++ drm_gem_object_get(bo->exclusive_vm_root_gem); ++ bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + + if (vm == panthor_fw_vm(ptdev)) + debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED; +@@ -168,9 +171,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + goto err_free_va; + + kbo->vm = panthor_vm_get(vm); +- bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); +- drm_gem_object_get(bo->exclusive_vm_root_gem); +- bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + return kbo; + + err_free_va: +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-group_free_queue-for-partially-initi.patch b/queue-6.17/drm-panthor-fix-group_free_queue-for-partially-initi.patch new file mode 100644 index 0000000000..ae98e64f87 --- /dev/null +++ b/queue-6.17/drm-panthor-fix-group_free_queue-for-partially-initi.patch @@ -0,0 +1,45 @@ +From d9e545bf4d1d41663b0426b1734f7d7e75137463 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:18 +0100 +Subject: drm/panthor: Fix group_free_queue() for partially initialized queues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Boris Brezillon + +[ Upstream commit 94a6d20feadbbe24e8a7b1c56394789ea5358fcc ] + +group_free_queue() can be called on a partially initialized queue +object if something fails in group_create_queue(). Make sure we don't +call drm_sched_entity_destroy() on an entity that hasn't been +initialized. + +Fixes: 7d9c3442b02a ("drm/panthor: Defer scheduler entitiy destruction to queue release") +Reviewed-by: Adrián Larumbe +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index a0a31aa6c6bcf..552542f70cabd 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -886,7 +886,8 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue * + if (IS_ERR_OR_NULL(queue)) + return; + +- drm_sched_entity_destroy(&queue->entity); ++ if (queue->entity.fence_context) ++ drm_sched_entity_destroy(&queue->entity); + + if (queue->scheduler.ops) + drm_sched_fini(&queue->scheduler); +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-potential-memleak-of-vma-structure.patch b/queue-6.17/drm-panthor-fix-potential-memleak-of-vma-structure.patch new file mode 100644 index 0000000000..123c12fe96 --- /dev/null +++ b/queue-6.17/drm-panthor-fix-potential-memleak-of-vma-structure.patch @@ -0,0 +1,69 @@ +From 0ce611de9306b4044eed5f156aadf53afead0e3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 09:10:42 +0100 +Subject: drm/panthor: Fix potential memleak of vma structure + +From: Akash Goel + +[ Upstream commit 4492d54d59872bb72e119ff9f77969ab4d8a0e6b ] + +This commit addresses a memleak issue of panthor_vma (or drm_gpuva) +structure in Panthor driver, that can happen if the GPU page table +update operation to map the pages fail. +The issue is very unlikely to occur in practice. + +v2: Add panthor_vm_op_ctx_return_vma() helper (Boris) + +v3: Add WARN_ON_ONCE (Boris) + +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patch.msgid.link/20251021081042.1377406-1-akash.goel@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c +index de6ec324c8efc..3d356a08695ab 100644 +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1118,6 +1118,20 @@ static void panthor_vm_cleanup_op_ctx(struct panthor_vm_op_ctx *op_ctx, + } + } + ++static void ++panthor_vm_op_ctx_return_vma(struct panthor_vm_op_ctx *op_ctx, ++ struct panthor_vma *vma) ++{ ++ for (u32 i = 0; i < ARRAY_SIZE(op_ctx->preallocated_vmas); i++) { ++ if (!op_ctx->preallocated_vmas[i]) { ++ op_ctx->preallocated_vmas[i] = vma; ++ return; ++ } ++ } ++ ++ WARN_ON_ONCE(1); ++} ++ + static struct panthor_vma * + panthor_vm_op_ctx_get_vma(struct panthor_vm_op_ctx *op_ctx) + { +@@ -2057,8 +2071,10 @@ static int panthor_gpuva_sm_step_map(struct drm_gpuva_op *op, void *priv) + ret = panthor_vm_map_pages(vm, op->map.va.addr, flags_to_prot(vma->flags), + op_ctx->map.sgt, op->map.gem.offset, + op->map.va.range); +- if (ret) ++ if (ret) { ++ panthor_vm_op_ctx_return_vma(op_ctx, vma); + return ret; ++ } + + /* Ref owned by the mapping now, clear the obj field so we don't release the + * pinning/obj ref behind GPUVA's back. +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-race-with-suspend-during-unplug.patch b/queue-6.17/drm-panthor-fix-race-with-suspend-during-unplug.patch new file mode 100644 index 0000000000..ef0d54d7bc --- /dev/null +++ b/queue-6.17/drm-panthor-fix-race-with-suspend-during-unplug.patch @@ -0,0 +1,58 @@ +From 80e94d7978575b0cdee1769e5ac36f8dbdbb3e3d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 12:32:41 +0200 +Subject: drm/panthor: Fix race with suspend during unplug + +From: Ketil Johnsen + +[ Upstream commit 08be57e6e8aa20ea5a6dd2552e38ac168d6a9b11 ] + +There is a race between panthor_device_unplug() and +panthor_device_suspend() which can lead to IRQ handlers running on a +powered down GPU. This is how it can happen: +- unplug routine calls drm_dev_unplug() +- panthor_device_suspend() can now execute, and will skip a lot of + important work because the device is currently marked as unplugged. +- IRQs will remain active in this case and IRQ handlers can therefore + try to access a powered down GPU. + +The fix is simply to take the PM ref in panthor_device_unplug() a +little bit earlier, before drm_dev_unplug(). + +Signed-off-by: Ketil Johnsen +Fixes: 5fe909cae118a ("drm/panthor: Add the device logical block") +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251022103242.1083311-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c +index f0b2da5b2b967..1c0a9337404f2 100644 +--- a/drivers/gpu/drm/panthor/panthor_device.c ++++ b/drivers/gpu/drm/panthor/panthor_device.c +@@ -82,6 +82,8 @@ void panthor_device_unplug(struct panthor_device *ptdev) + return; + } + ++ drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); ++ + /* Call drm_dev_unplug() so any access to HW blocks happening after + * that point get rejected. + */ +@@ -92,8 +94,6 @@ void panthor_device_unplug(struct panthor_device *ptdev) + */ + mutex_unlock(&ptdev->unplug.lock); + +- drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); +- + /* Now, try to cleanly shutdown the GPU before the device resources + * get reclaimed. + */ +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch b/queue-6.17/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch new file mode 100644 index 0000000000..3a21f4f1e9 --- /dev/null +++ b/queue-6.17/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch @@ -0,0 +1,68 @@ +From d5782ef684a7ccc3a088698dd8bab21f237c86e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:48:15 +0100 +Subject: drm/panthor: Fix UAF on kernel BO VA nodes + +From: Boris Brezillon + +[ Upstream commit 98dd5143447af0ee33551776d8b2560c35d0bc4a ] + +If the MMU is down, panthor_vm_unmap_range() might return an error. +We expect the page table to be updated still, and if the MMU is blocked, +the rest of the GPU should be blocked too, so no risk of accessing +physical memory returned to the system (which the current code doesn't +cover for anyway). + +Proceed with the rest of the cleanup instead of bailing out and leaving +the va_node inserted in the drm_mm, which leads to UAF when other +adjacent nodes are removed from the drm_mm tree. + +Reported-by: Lars-Ivar Hesselberg Simonsen +Closes: https://gitlab.freedesktop.org/panfrost/linux/-/issues/57 +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251031154818.821054-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index eb5f0b9d437fc..6830a89a7c10b 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -87,7 +87,6 @@ static void panthor_gem_free_object(struct drm_gem_object *obj) + void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + { + struct panthor_vm *vm; +- int ret; + + if (IS_ERR_OR_NULL(bo)) + return; +@@ -95,18 +94,11 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + vm = bo->vm; + panthor_kernel_bo_vunmap(bo); + +- if (drm_WARN_ON(bo->obj->dev, +- to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) +- goto out_free_bo; +- +- ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); +- if (ret) +- goto out_free_bo; +- ++ drm_WARN_ON(bo->obj->dev, ++ to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)); ++ panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); + panthor_vm_free_va(vm, &bo->va_node); + drm_gem_object_put(bo->obj); +- +-out_free_bo: + panthor_vm_put(vm); + kfree(bo); + } +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch b/queue-6.17/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch new file mode 100644 index 0000000000..da54a9c828 --- /dev/null +++ b/queue-6.17/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch @@ -0,0 +1,43 @@ +From 7c237a8de7b4f677115eede8e4bacb7058e40229 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:02:15 +0100 +Subject: drm/panthor: Fix UAF race between device unplug and FW event + processing + +From: Ketil Johnsen + +[ Upstream commit 7051f6ba968fa69918d72cc26de4d6cf7ea05b90 ] + +The function panthor_fw_unplug() will free the FW memory sections. +The problem is that there could still be pending FW events which are yet +not handled at this point. process_fw_events_work() can in this case try +to access said freed memory. + +Simply call disable_work_sync() to both drain and prevent future +invocation of process_fw_events_work(). + +Signed-off-by: Ketil Johnsen +Fixes: de85488138247 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251027140217.121274-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 552542f70cabd..99ce0948f2bae 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3826,6 +3826,7 @@ void panthor_sched_unplug(struct panthor_device *ptdev) + struct panthor_scheduler *sched = ptdev->scheduler; + + cancel_delayed_work_sync(&sched->tick_work); ++ disable_work_sync(&sched->fw_events_work); + + mutex_lock(&sched->lock); + if (sched->pm.has_ref) { +-- +2.51.0 + diff --git a/queue-6.17/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch b/queue-6.17/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch new file mode 100644 index 0000000000..36a0d90ea4 --- /dev/null +++ b/queue-6.17/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch @@ -0,0 +1,39 @@ +From dceeb52c92dd4313fb10884e2d7f36d4f725a554 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:17 +0100 +Subject: drm/panthor: Handle errors returned by drm_sched_entity_init() + +From: Boris Brezillon + +[ Upstream commit bb7939e332c64c4ef33974a0eae4f3841acfa8eb ] + +In practice it's not going to fail because we're passing the current +sanity checks done by drm_sched_entity_init(), and that's the only +reason it would return an error, but better safe than sorry. + +Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-1-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index df76653e649a3..a0a31aa6c6bcf 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3380,6 +3380,8 @@ group_create_queue(struct panthor_group *group, + + drm_sched = &queue->scheduler; + ret = drm_sched_entity_init(&queue->entity, 0, &drm_sched, 1, NULL); ++ if (ret) ++ goto err_free_queue; + + return queue; + +-- +2.51.0 + diff --git a/queue-6.17/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch b/queue-6.17/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch new file mode 100644 index 0000000000..57f96c39b0 --- /dev/null +++ b/queue-6.17/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch @@ -0,0 +1,134 @@ +From 561209d957cab2c692fbca0a20a7f495d26db092 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:44:22 +0530 +Subject: drm/tidss: Move OLDI mode validation to OLDI bridge mode_valid hook + +From: Jayesh Choudhary + +[ Upstream commit 86db652fc22f5674ffe3b1f7c91c397c69d26d94 ] + +After integrating OLDI support[0], it is necessary to identify which VP +instances use OLDI, since the OLDI driver owns the video port clock +(as a serial clock). Clock operations on these VPs must be delegated to +the OLDI driver, not handled by the TIDSS driver. This issue also +emerged in upstream discussions when DSI-related clock management was +attempted in the TIDSS driver[1]. + +To address this, add an 'is_ext_vp_clk' array to the 'tidss_device' +structure, marking a VP as 'true' during 'tidss_oldi_init()' and as +'false' during 'tidss_oldi_deinit()'. TIDSS then uses 'is_ext_vp_clk' +to skip clock validation checks in 'dispc_vp_mode_valid()' for VPs +under OLDI control. + +Since OLDI uses the DSS VP clock directly as a serial interface and +manages its own rate, mode validation should be implemented in the OLDI +bridge's 'mode_valid' hook. This patch adds that logic, ensuring proper +delegation and avoiding spurious clock handling in the TIDSS driver. + +[0]: https://lore.kernel.org/all/20250528122544.817829-1-aradhya.bhatia@linux.dev/ +[1]: https://lore.kernel.org/all/DA6TT575Z82D.3MPK8HG5GRL8U@kernel.org/ + +Fixes: 7246e0929945 ("drm/tidss: Add OLDI bridge support") +Tested-by: Michael Walle +Reviewed-by: Devarsh Thakkar +Reviewed-by: Tomi Valkeinen +Signed-off-by: Jayesh Choudhary +Signed-off-by: Swamil Jain +Link: https://patch.msgid.link/20251104151422.307162-3-s-jain1@ti.com +Signed-off-by: Tomi Valkeinen +Link: https://patch.msgid.link/ffd5ebe03391b3c01e616c0c844a4b8ddecede36.1762513240.git.jani.nikula@intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 7 +++++++ + drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ + drivers/gpu/drm/tidss/tidss_oldi.c | 22 ++++++++++++++++++++++ + 3 files changed, 31 insertions(+) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 85048ac44608a..50ccf48ed492c 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -1329,6 +1329,13 @@ static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, + { + unsigned long round_clock; + ++ /* ++ * For VP's with external clocking, clock operations must be ++ * delegated to respective driver, so we skip the check here. ++ */ ++ if (dispc->tidss->is_ext_vp_clk[hw_videoport]) ++ return 0; ++ + round_clock = clk_round_rate(dispc->vp_clk[hw_videoport], clock); + /* + * To keep the check consistent with dispc_vp_set_clk_rate(), we +diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h +index d14d5d28f0a33..4e38cfa99e840 100644 +--- a/drivers/gpu/drm/tidss/tidss_drv.h ++++ b/drivers/gpu/drm/tidss/tidss_drv.h +@@ -22,6 +22,8 @@ struct tidss_device { + + const struct dispc_features *feat; + struct dispc_device *dispc; ++ bool is_ext_vp_clk[TIDSS_MAX_PORTS]; ++ + + unsigned int num_crtcs; + struct drm_crtc *crtcs[TIDSS_MAX_PORTS]; +diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c +index 8f25159d0666a..d24b1e3cdce01 100644 +--- a/drivers/gpu/drm/tidss/tidss_oldi.c ++++ b/drivers/gpu/drm/tidss/tidss_oldi.c +@@ -309,6 +309,25 @@ static u32 *tidss_oldi_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + return input_fmts; + } + ++static enum drm_mode_status ++tidss_oldi_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) ++{ ++ struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); ++ unsigned long round_clock; ++ ++ round_clock = clk_round_rate(oldi->serial, mode->clock * 7 * 1000); ++ /* ++ * To keep the check consistent with dispc_vp_set_clk_rate(), ++ * we use the same 5% check here. ++ */ ++ if (dispc_pclk_diff(mode->clock * 7 * 1000, round_clock) > 5) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = { + .attach = tidss_oldi_bridge_attach, + .atomic_pre_enable = tidss_oldi_atomic_pre_enable, +@@ -317,6 +336,7 @@ static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, ++ .mode_valid = tidss_oldi_mode_valid, + }; + + static int get_oldi_mode(struct device_node *oldi_tx, int *companion_instance) +@@ -430,6 +450,7 @@ void tidss_oldi_deinit(struct tidss_device *tidss) + for (int i = 0; i < tidss->num_oldis; i++) { + if (tidss->oldis[i]) { + drm_bridge_remove(&tidss->oldis[i]->bridge); ++ tidss->is_ext_vp_clk[tidss->oldis[i]->parent_vp] = false; + tidss->oldis[i] = NULL; + } + } +@@ -581,6 +602,7 @@ int tidss_oldi_init(struct tidss_device *tidss) + oldi->bridge.timings = &default_tidss_oldi_timings; + + tidss->oldis[tidss->num_oldis++] = oldi; ++ tidss->is_ext_vp_clk[oldi->parent_vp] = true; + oldi->tidss = tidss; + + drm_bridge_add(&oldi->bridge); +-- +2.51.0 + diff --git a/queue-6.17/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch b/queue-6.17/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch new file mode 100644 index 0000000000..e6ad305266 --- /dev/null +++ b/queue-6.17/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch @@ -0,0 +1,229 @@ +From e9bd43c13c8c8045465efd1957933dd5ec992eeb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:44:21 +0530 +Subject: drm/tidss: Remove max_pclk_khz and min_pclk_khz from tidss display + features + +From: Jayesh Choudhary + +[ Upstream commit 527e132573dfa793818a536b18eec49598a6f6f5 ] + +The TIDSS hardware does not have independent maximum or minimum pixel +clock limits for each video port. Instead, these limits are determined +by the SoC's clock architecture. Previously, this constraint was +modeled using the 'max_pclk_khz' and 'min_pclk_khz' fields in +'dispc_features', but this approach is static and does not account for +the dynamic behavior of PLLs. + +This patch removes the 'max_pclk_khz' and 'min_pclk_khz' fields from +'dispc_features'. The correct way to check if a requested mode's pixel +clock is supported is by using 'clk_round_rate()' in the 'mode_valid()' +hook. If the best frequency match for the mode clock falls within the +supported tolerance, it is approved. TIDSS supports a 5% pixel clock +tolerance, which is now reflected in the validation logic. + +This change allows existing DSS-compatible drivers to be reused across +SoCs that only differ in their pixel clock characteristics. The +validation uses 'clk_round_rate()' for each mode, which may introduce +additional delay (about 3.5 ms for 30 modes), but this is generally +negligible. Users desiring faster validation may bypass these calls +selectively, for example, checking only the highest resolution mode, +as shown here[1]. + +[1]: https://lore.kernel.org/all/20250704094851.182131-3-j-choudhary@ti.com/ + +Tested-by: Michael Walle +Reviewed-by: Devarsh Thakkar +Reviewed-by: Tomi Valkeinen +Signed-off-by: Jayesh Choudhary +Signed-off-by: Swamil Jain +Link: https://patch.msgid.link/20251104151422.307162-2-s-jain1@ti.com +[Tomi: dropped 'inline' from check_pixel_clock] +Signed-off-by: Tomi Valkeinen +Stable-dep-of: 86db652fc22f ("drm/tidss: Move OLDI mode validation to OLDI bridge mode_valid hook") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 86 +++++++++++------------------ + drivers/gpu/drm/tidss/tidss_dispc.h | 3 - + 2 files changed, 31 insertions(+), 58 deletions(-) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 3f6cff2ab1b29..85048ac44608a 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -56,12 +56,6 @@ static const u16 tidss_k2g_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_k2g_feats = { +- .min_pclk_khz = 4375, +- +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 150000, +- }, +- + /* + * XXX According TRM the RGB input buffer width up to 2560 should + * work on 3 taps, but in practice it only works up to 1280. +@@ -144,11 +138,6 @@ static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_am65x_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- [DISPC_VP_OLDI_AM65X] = 165000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -244,11 +233,6 @@ static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_j721e_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 170000, +- [DISPC_VP_INTERNAL] = 600000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 2048, + .in_width_max_3tap_rgb = 4096, +@@ -315,11 +299,6 @@ const struct dispc_features dispc_j721e_feats = { + }; + + const struct dispc_features dispc_am625_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- [DISPC_VP_INTERNAL] = 170000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -376,15 +355,6 @@ const struct dispc_features dispc_am625_feats = { + }; + + const struct dispc_features dispc_am62a7_feats = { +- /* +- * if the code reaches dispc_mode_valid with VP1, +- * it should return MODE_BAD. +- */ +- .max_pclk_khz = { +- [DISPC_VP_TIED_OFF] = 0, +- [DISPC_VP_DPI] = 165000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -441,10 +411,6 @@ const struct dispc_features dispc_am62a7_feats = { + }; + + const struct dispc_features dispc_am62l_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- }, +- + .subrev = DISPC_AM62L, + + .common = "common", +@@ -1347,33 +1313,54 @@ static void dispc_vp_set_default_color(struct dispc_device *dispc, + DISPC_OVR_DEFAULT_COLOR2, (v >> 32) & 0xffff); + } + ++/* ++ * Calculate the percentage difference between the requested pixel clock rate ++ * and the effective rate resulting from calculating the clock divider value. ++ */ ++unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) ++{ ++ int r = rate / 100, rr = real_rate / 100; ++ ++ return (unsigned int)(abs(((rr - r) * 100) / r)); ++} ++ ++static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, ++ unsigned long clock) ++{ ++ unsigned long round_clock; ++ ++ round_clock = clk_round_rate(dispc->vp_clk[hw_videoport], clock); ++ /* ++ * To keep the check consistent with dispc_vp_set_clk_rate(), we ++ * use the same 5% check here. ++ */ ++ if (dispc_pclk_diff(clock, round_clock) > 5) ++ return -EINVAL; ++ ++ return 0; ++} ++ + enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc, + u32 hw_videoport, + const struct drm_display_mode *mode) + { + u32 hsw, hfp, hbp, vsw, vfp, vbp; + enum dispc_vp_bus_type bus_type; +- int max_pclk; + + bus_type = dispc->feat->vp_bus_type[hw_videoport]; + +- max_pclk = dispc->feat->max_pclk_khz[bus_type]; +- +- if (WARN_ON(max_pclk == 0)) ++ if (WARN_ON(bus_type == DISPC_VP_TIED_OFF)) + return MODE_BAD; + +- if (mode->clock < dispc->feat->min_pclk_khz) +- return MODE_CLOCK_LOW; +- +- if (mode->clock > max_pclk) +- return MODE_CLOCK_HIGH; +- + if (mode->hdisplay > 4096) + return MODE_BAD; + + if (mode->vdisplay > 4096) + return MODE_BAD; + ++ if (check_pixel_clock(dispc, hw_videoport, mode->clock * 1000)) ++ return MODE_CLOCK_RANGE; ++ + /* TODO: add interlace support */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; +@@ -1437,17 +1424,6 @@ void dispc_vp_disable_clk(struct dispc_device *dispc, u32 hw_videoport) + clk_disable_unprepare(dispc->vp_clk[hw_videoport]); + } + +-/* +- * Calculate the percentage difference between the requested pixel clock rate +- * and the effective rate resulting from calculating the clock divider value. +- */ +-unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) +-{ +- int r = rate / 100, rr = real_rate / 100; +- +- return (unsigned int)(abs(((rr - r) * 100) / r)); +-} +- + int dispc_vp_set_clk_rate(struct dispc_device *dispc, u32 hw_videoport, + unsigned long rate) + { +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h +index b8614f62186ce..3979aed6413ba 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.h ++++ b/drivers/gpu/drm/tidss/tidss_dispc.h +@@ -74,9 +74,6 @@ enum dispc_dss_subrevision { + }; + + struct dispc_features { +- int min_pclk_khz; +- int max_pclk_khz[DISPC_VP_MAX_BUS_TYPE]; +- + struct dispc_features_scaling scaling; + + enum dispc_dss_subrevision subrev; +-- +2.51.0 + diff --git a/queue-6.17/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-6.17/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..714f4d9167 --- /dev/null +++ b/queue-6.17/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From ed8a18e807389ea4c518fd2eccb2a7f7a604188f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index fd76730fd38c0..07db319c3d7f9 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -79,7 +79,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.17/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch b/queue-6.17/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch new file mode 100644 index 0000000000..35ea9ef70e --- /dev/null +++ b/queue-6.17/dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch @@ -0,0 +1,185 @@ +From 468c25737f5eb67e48f32fd1f762b909179964bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 20:14:38 +0200 +Subject: dt-bindings: clock: qcom,x1e80100-gcc: Add missing USB4 clocks/resets + +From: Konrad Dybcio + +[ Upstream commit e4c4f5a1ae18a7828c2bfaf9dfe2473632b92d1b ] + +Some of the USB4 muxes, RCGs and resets were not initially described. + +Add indices for them to allow extending the driver. + +Acked-by: Rob Herring (Arm) +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251003-topic-hamoa_gcc_usb4-v2-1-61d27a14ee65@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Stable-dep-of: 8abe970efea5 ("clk: qcom: gcc-x1e80100: Add missing USB4 clocks/resets") +Signed-off-by: Sasha Levin +--- + .../bindings/clock/qcom,x1e80100-gcc.yaml | 62 +++++++++++++++++-- + include/dt-bindings/clock/qcom,x1e80100-gcc.h | 61 ++++++++++++++++++ + 2 files changed, 119 insertions(+), 4 deletions(-) + +diff --git a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +index 68dde0720c711..1b15b50709545 100644 +--- a/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml ++++ b/Documentation/devicetree/bindings/clock/qcom,x1e80100-gcc.yaml +@@ -32,9 +32,36 @@ properties: + - description: PCIe 5 pipe clock + - description: PCIe 6a pipe clock + - description: PCIe 6b pipe clock +- - description: USB QMP Phy 0 clock source +- - description: USB QMP Phy 1 clock source +- - description: USB QMP Phy 2 clock source ++ - description: USB4_0 QMPPHY clock source ++ - description: USB4_1 QMPPHY clock source ++ - description: USB4_2 QMPPHY clock source ++ - description: USB4_0 PHY DP0 GMUX clock source ++ - description: USB4_0 PHY DP1 GMUX clock source ++ - description: USB4_0 PHY PCIE PIPEGMUX clock source ++ - description: USB4_0 PHY PIPEGMUX clock source ++ - description: USB4_0 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_1 PHY DP0 GMUX 2 clock source ++ - description: USB4_1 PHY DP1 GMUX 2 clock source ++ - description: USB4_1 PHY PCIE PIPEGMUX clock source ++ - description: USB4_1 PHY PIPEGMUX clock source ++ - description: USB4_1 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_2 PHY DP0 GMUX 2 clock source ++ - description: USB4_2 PHY DP1 GMUX 2 clock source ++ - description: USB4_2 PHY PCIE PIPEGMUX clock source ++ - description: USB4_2 PHY PIPEGMUX clock source ++ - description: USB4_2 PHY SYS PCIE PIPEGMUX clock source ++ - description: USB4_0 PHY RX 0 clock source ++ - description: USB4_0 PHY RX 1 clock source ++ - description: USB4_1 PHY RX 0 clock source ++ - description: USB4_1 PHY RX 1 clock source ++ - description: USB4_2 PHY RX 0 clock source ++ - description: USB4_2 PHY RX 1 clock source ++ - description: USB4_0 PHY PCIE PIPE clock source ++ - description: USB4_0 PHY max PIPE clock source ++ - description: USB4_1 PHY PCIE PIPE clock source ++ - description: USB4_1 PHY max PIPE clock source ++ - description: USB4_2 PHY PCIE PIPE clock source ++ - description: USB4_2 PHY max PIPE clock source + + power-domains: + description: +@@ -67,7 +94,34 @@ examples: + <&pcie6b_phy>, + <&usb_1_ss0_qmpphy 0>, + <&usb_1_ss1_qmpphy 1>, +- <&usb_1_ss2_qmpphy 2>; ++ <&usb_1_ss2_qmpphy 2>, ++ <&usb4_0_phy_dp0_gmux_clk>, ++ <&usb4_0_phy_dp1_gmux_clk>, ++ <&usb4_0_phy_pcie_pipegmux_clk>, ++ <&usb4_0_phy_pipegmux_clk>, ++ <&usb4_0_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_1_phy_dp0_gmux_2_clk>, ++ <&usb4_1_phy_dp1_gmux_2_clk>, ++ <&usb4_1_phy_pcie_pipegmux_clk>, ++ <&usb4_1_phy_pipegmux_clk>, ++ <&usb4_1_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_2_phy_dp0_gmux_2_clk>, ++ <&usb4_2_phy_dp1_gmux_2_clk>, ++ <&usb4_2_phy_pcie_pipegmux_clk>, ++ <&usb4_2_phy_pipegmux_clk>, ++ <&usb4_2_phy_sys_pcie_pipegmux_clk>, ++ <&usb4_0_phy_rx_0_clk>, ++ <&usb4_0_phy_rx_1_clk>, ++ <&usb4_1_phy_rx_0_clk>, ++ <&usb4_1_phy_rx_1_clk>, ++ <&usb4_2_phy_rx_0_clk>, ++ <&usb4_2_phy_rx_1_clk>, ++ <&usb4_0_phy_pcie_pipe_clk>, ++ <&usb4_0_phy_max_pipe_clk>, ++ <&usb4_1_phy_pcie_pipe_clk>, ++ <&usb4_1_phy_max_pipe_clk>, ++ <&usb4_2_phy_pcie_pipe_clk>, ++ <&usb4_2_phy_max_pipe_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; + #reset-cells = <1>; +diff --git a/include/dt-bindings/clock/qcom,x1e80100-gcc.h b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +index 710c340f24a57..62aa124255927 100644 +--- a/include/dt-bindings/clock/qcom,x1e80100-gcc.h ++++ b/include/dt-bindings/clock/qcom,x1e80100-gcc.h +@@ -363,6 +363,30 @@ + #define GCC_USB3_PRIM_PHY_PIPE_CLK_SRC 353 + #define GCC_USB3_SEC_PHY_PIPE_CLK_SRC 354 + #define GCC_USB3_TERT_PHY_PIPE_CLK_SRC 355 ++#define GCC_USB34_PRIM_PHY_PIPE_CLK_SRC 356 ++#define GCC_USB34_SEC_PHY_PIPE_CLK_SRC 357 ++#define GCC_USB34_TERT_PHY_PIPE_CLK_SRC 358 ++#define GCC_USB4_0_PHY_DP0_CLK_SRC 359 ++#define GCC_USB4_0_PHY_DP1_CLK_SRC 360 ++#define GCC_USB4_0_PHY_P2RR2P_PIPE_CLK_SRC 361 ++#define GCC_USB4_0_PHY_PCIE_PIPE_MUX_CLK_SRC 362 ++#define GCC_USB4_0_PHY_RX0_CLK_SRC 363 ++#define GCC_USB4_0_PHY_RX1_CLK_SRC 364 ++#define GCC_USB4_0_PHY_SYS_CLK_SRC 365 ++#define GCC_USB4_1_PHY_DP0_CLK_SRC 366 ++#define GCC_USB4_1_PHY_DP1_CLK_SRC 367 ++#define GCC_USB4_1_PHY_P2RR2P_PIPE_CLK_SRC 368 ++#define GCC_USB4_1_PHY_PCIE_PIPE_MUX_CLK_SRC 369 ++#define GCC_USB4_1_PHY_RX0_CLK_SRC 370 ++#define GCC_USB4_1_PHY_RX1_CLK_SRC 371 ++#define GCC_USB4_1_PHY_SYS_CLK_SRC 372 ++#define GCC_USB4_2_PHY_DP0_CLK_SRC 373 ++#define GCC_USB4_2_PHY_DP1_CLK_SRC 374 ++#define GCC_USB4_2_PHY_P2RR2P_PIPE_CLK_SRC 375 ++#define GCC_USB4_2_PHY_PCIE_PIPE_MUX_CLK_SRC 376 ++#define GCC_USB4_2_PHY_RX0_CLK_SRC 377 ++#define GCC_USB4_2_PHY_RX1_CLK_SRC 378 ++#define GCC_USB4_2_PHY_SYS_CLK_SRC 379 + + /* GCC power domains */ + #define GCC_PCIE_0_TUNNEL_GDSC 0 +@@ -484,4 +508,41 @@ + #define GCC_VIDEO_BCR 87 + #define GCC_VIDEO_AXI0_CLK_ARES 88 + #define GCC_VIDEO_AXI1_CLK_ARES 89 ++#define GCC_USB4_0_MISC_USB4_SYS_BCR 90 ++#define GCC_USB4_0_MISC_RX_CLK_0_BCR 91 ++#define GCC_USB4_0_MISC_RX_CLK_1_BCR 92 ++#define GCC_USB4_0_MISC_USB_PIPE_BCR 93 ++#define GCC_USB4_0_MISC_PCIE_PIPE_BCR 94 ++#define GCC_USB4_0_MISC_TMU_BCR 95 ++#define GCC_USB4_0_MISC_SB_IF_BCR 96 ++#define GCC_USB4_0_MISC_HIA_MSTR_BCR 97 ++#define GCC_USB4_0_MISC_AHB_BCR 98 ++#define GCC_USB4_0_MISC_DP0_MAX_PCLK_BCR 99 ++#define GCC_USB4_0_MISC_DP1_MAX_PCLK_BCR 100 ++#define GCC_USB4_1_MISC_USB4_SYS_BCR 101 ++#define GCC_USB4_1_MISC_RX_CLK_0_BCR 102 ++#define GCC_USB4_1_MISC_RX_CLK_1_BCR 103 ++#define GCC_USB4_1_MISC_USB_PIPE_BCR 104 ++#define GCC_USB4_1_MISC_PCIE_PIPE_BCR 105 ++#define GCC_USB4_1_MISC_TMU_BCR 106 ++#define GCC_USB4_1_MISC_SB_IF_BCR 107 ++#define GCC_USB4_1_MISC_HIA_MSTR_BCR 108 ++#define GCC_USB4_1_MISC_AHB_BCR 109 ++#define GCC_USB4_1_MISC_DP0_MAX_PCLK_BCR 110 ++#define GCC_USB4_1_MISC_DP1_MAX_PCLK_BCR 111 ++#define GCC_USB4_2_MISC_USB4_SYS_BCR 112 ++#define GCC_USB4_2_MISC_RX_CLK_0_BCR 113 ++#define GCC_USB4_2_MISC_RX_CLK_1_BCR 114 ++#define GCC_USB4_2_MISC_USB_PIPE_BCR 115 ++#define GCC_USB4_2_MISC_PCIE_PIPE_BCR 116 ++#define GCC_USB4_2_MISC_TMU_BCR 117 ++#define GCC_USB4_2_MISC_SB_IF_BCR 118 ++#define GCC_USB4_2_MISC_HIA_MSTR_BCR 119 ++#define GCC_USB4_2_MISC_AHB_BCR 120 ++#define GCC_USB4_2_MISC_DP0_MAX_PCLK_BCR 121 ++#define GCC_USB4_2_MISC_DP1_MAX_PCLK_BCR 122 ++#define GCC_USB4PHY_PHY_PRIM_BCR 123 ++#define GCC_USB4PHY_PHY_SEC_BCR 124 ++#define GCC_USB4PHY_PHY_TERT_BCR 125 ++ + #endif +-- +2.51.0 + diff --git a/queue-6.17/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-6.17/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..03b4dbaf18 --- /dev/null +++ b/queue-6.17/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From 6c8fc5869afec1b726d2a12419183fd3cbf1a4c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index 79a21ba0f9fd6..c8258ef403283 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-6.17/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch b/queue-6.17/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch new file mode 100644 index 0000000000..12852fec69 --- /dev/null +++ b/queue-6.17/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch @@ -0,0 +1,71 @@ +From 197791881e2cba079af55c21d74e3e484e5e8d37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:23 +0000 +Subject: efi/libstub: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit 84361123413efc84b06f3441c6c827b95d902732 ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags Bits above the + physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The pgd value is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c +index f1c5fb45d5f7c..c00d0ae7ed5d5 100644 +--- a/drivers/firmware/efi/libstub/x86-5lvl.c ++++ b/drivers/firmware/efi/libstub/x86-5lvl.c +@@ -66,7 +66,7 @@ void efi_5level_switch(void) + bool have_la57 = native_read_cr4() & X86_CR4_LA57; + bool need_toggle = want_la57 ^ have_la57; + u64 *pgt = (void *)la57_toggle + PAGE_SIZE; +- u64 *cr3 = (u64 *)__native_read_cr3(); ++ pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); + u64 *new_cr3; + + if (!la57_toggle || !need_toggle) +@@ -82,7 +82,7 @@ void efi_5level_switch(void) + new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; + } else { + /* take the new root table pointer from the current entry #0 */ +- new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); ++ new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); + + /* copy the new root table if it is not 32-bit addressable */ + if ((u64)new_cr3 > U32_MAX) +-- +2.51.0 + diff --git a/queue-6.17/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch b/queue-6.17/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch new file mode 100644 index 0000000000..deff8b34fc --- /dev/null +++ b/queue-6.17/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch @@ -0,0 +1,51 @@ +From 23f26c8342e1b5cb000e3bff711e7af6f475a33d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 11:00:14 +0100 +Subject: entry,unwind/deferred: Fix unwind_reset_info() placement + +From: Peter Zijlstra + +[ Upstream commit cf76553aaa363620f58a6b6409bf544f4bcfa8de ] + +Stephen reported that on KASAN builds he's seeing: + +vmlinux.o: warning: objtool: user_exc_vmm_communication+0x15a: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: exc_debug_user+0x182: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: exc_int3+0x123: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: noist_exc_machine_check+0x17a: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: fred_exc_machine_check+0x17e: call to __kasan_check_read() leaves .noinstr.text section + +This turns out to be atomic ops from unwind_reset_info() that have +explicit instrumentation. Place unwind_reset_info() in the preceding +instrumentation_begin() section. + +Fixes: c6439bfaabf2 ("Merge tag 'trace-deferred-unwind-v6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace") +Reported-by: Stephen Rothwell +Reported-by: Ingo Molnar +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251105100014.GY4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + include/linux/irq-entry-common.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h +index d643c7c87822e..ba1ed42f8a1c2 100644 +--- a/include/linux/irq-entry-common.h ++++ b/include/linux/irq-entry-common.h +@@ -253,11 +253,11 @@ static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs) + static __always_inline void exit_to_user_mode(void) + { + instrumentation_begin(); ++ unwind_reset_info(); + trace_hardirqs_on_prepare(); + lockdep_hardirqs_on_prepare(); + instrumentation_end(); + +- unwind_reset_info(); + user_enter_irqoff(); + arch_exit_to_user_mode(); + lockdep_hardirqs_on(CALLER_ADDR0); +-- +2.51.0 + diff --git a/queue-6.17/erofs-correct-fsdax-detection.patch b/queue-6.17/erofs-correct-fsdax-detection.patch new file mode 100644 index 0000000000..542e139c15 --- /dev/null +++ b/queue-6.17/erofs-correct-fsdax-detection.patch @@ -0,0 +1,73 @@ +From bc6a3b759d4291812382addb605611ad81ddd000 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 19:57:29 +0800 +Subject: erofs: correct FSDAX detection + +From: Gao Xiang + +[ Upstream commit ebe4f3f6eb0c10f87c58e52a8912694c14fdeda6 ] + +The detection of the primary device is skipped incorrectly +if the multiple or flattened feature is enabled. + +It also fixes the FSDAX misdetection for non-block extra blobs. + +Fixes: c6993c4cb918 ("erofs: Fallback to normal access if DAX is not supported on extra device") +Reported-and-tested-by: syzbot+31b8fb02cb8a25bd5e78@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/r/691af9f6.a70a0220.3124cb.0097.GAE@google.com +Cc: Yuezhang Mo +Reviewed-by: Chao Yu +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/super.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/fs/erofs/super.c b/fs/erofs/super.c +index db13b40a78e07..edac533a389cb 100644 +--- a/fs/erofs/super.c ++++ b/fs/erofs/super.c +@@ -174,15 +174,15 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb, + if (!erofs_is_fileio_mode(sbi)) { + dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file), + &dif->dax_part_off, NULL, NULL); +- if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) { +- erofs_info(sb, "DAX unsupported by %s. Turning off DAX.", +- dif->path); +- clear_opt(&sbi->opt, DAX_ALWAYS); +- } + } else if (!S_ISREG(file_inode(file)->i_mode)) { + fput(file); + return -EINVAL; + } ++ if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) { ++ erofs_info(sb, "DAX unsupported by %s. Turning off DAX.", ++ dif->path); ++ clear_opt(&sbi->opt, DAX_ALWAYS); ++ } + dif->file = file; + } + +@@ -215,13 +215,13 @@ static int erofs_scan_devices(struct super_block *sb, + ondisk_extradevs, sbi->devs->extra_devices); + return -EINVAL; + } +- if (!ondisk_extradevs) { +- if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) { +- erofs_info(sb, "DAX unsupported by block device. Turning off DAX."); +- clear_opt(&sbi->opt, DAX_ALWAYS); +- } +- return 0; ++ ++ if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) { ++ erofs_info(sb, "DAX unsupported by block device. Turning off DAX."); ++ clear_opt(&sbi->opt, DAX_ALWAYS); + } ++ if (!ondisk_extradevs) ++ return 0; + + if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb)) + sbi->devs->flatdev = true; +-- +2.51.0 + diff --git a/queue-6.17/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch b/queue-6.17/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch new file mode 100644 index 0000000000..462602dad6 --- /dev/null +++ b/queue-6.17/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch @@ -0,0 +1,52 @@ +From d69b550751702bdf2b153abe393a180a57d014db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 14:23:32 +0800 +Subject: erofs: limit the level of fs stacking for file-backed mounts + +From: Gao Xiang + +[ Upstream commit d53cd891f0e4311889349fff3a784dc552f814b9 ] + +Otherwise, it could cause potential kernel stack overflow (e.g., EROFS +mounting itself). + +Reviewed-by: Sheng Yong +Fixes: fb176750266a ("erofs: add file-backed mount support") +Reviewed-by: Chao Yu +Reviewed-by: Hongbo Li +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/super.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/fs/erofs/super.c b/fs/erofs/super.c +index edac533a389cb..32336e7c1d9b6 100644 +--- a/fs/erofs/super.c ++++ b/fs/erofs/super.c +@@ -632,6 +632,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) + + sbi->blkszbits = PAGE_SHIFT; + if (!sb->s_bdev) { ++ /* ++ * (File-backed mounts) EROFS claims it's safe to nest other ++ * fs contexts (including its own) due to self-controlled RO ++ * accesses/contexts and no side-effect changes that need to ++ * context save & restore so it can reuse the current thread ++ * context. However, it still needs to bump `s_stack_depth` to ++ * avoid kernel stack overflow from nested filesystems. ++ */ ++ if (erofs_is_fileio_mode(sbi)) { ++ sb->s_stack_depth = ++ file_inode(sbi->dif0.file)->i_sb->s_stack_depth + 1; ++ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { ++ erofs_err(sb, "maximum fs stacking depth exceeded"); ++ return -ENOTBLK; ++ } ++ } + sb->s_blocksize = PAGE_SIZE; + sb->s_blocksize_bits = PAGE_SHIFT; + +-- +2.51.0 + diff --git a/queue-6.17/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-6.17/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..e59e53d60d --- /dev/null +++ b/queue-6.17/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From 86f85acab75930c20b5c52064a8ce6f1d13980ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 4b091c21908fd..0f4b7c89edd39 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -485,7 +485,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-6.17/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-6.17/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..f15eaab33f --- /dev/null +++ b/queue-6.17/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From 742b9418b07437cfe9e547374d24094eda77837e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 6070d3c86678e..80d6944755b8a 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -682,6 +682,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -723,15 +741,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -747,15 +756,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-6.17/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-6.17/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..c716a1fcc5 --- /dev/null +++ b/queue-6.17/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From 1653c1ce0723cc9f951781de48812433845fa5be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index aa6cc0a8151ac..83dd31fa1fab5 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -680,7 +680,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -757,6 +757,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-6.17/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-6.17/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..8d14e92087 --- /dev/null +++ b/queue-6.17/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From a27de03ba6dfd99c059adf9a19e9072b48aa4075 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index 6125cccc9ba79..f2b902e95b738 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-6.17/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch b/queue-6.17/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch new file mode 100644 index 0000000000..f00d72dc68 --- /dev/null +++ b/queue-6.17/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch @@ -0,0 +1,59 @@ +From 5c3b4f9d2c5a8f3fd31e303070066ac8c048a0cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 12:13:23 -0700 +Subject: firmware: qcom: tzmem: fix qcom_tzmem_policy kernel-doc + +From: Randy Dunlap + +[ Upstream commit edd548dc64a699d71ea4f537f815044e763d01e1 ] + +Fix kernel-doc warnings by using correct kernel-doc syntax and +formatting to prevent warnings: + +Warning: include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_STATIC' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_MULTIPLIER' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_ON_DEMAND' not described in enum 'qcom_tzmem_policy' + +Fixes: 84f5a7b67b61 ("firmware: qcom: add a dedicated TrustZone buffer allocator") +Signed-off-by: Randy Dunlap +Link: https://lore.kernel.org/r/20251017191323.1820167-1-rdunlap@infradead.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + include/linux/firmware/qcom/qcom_tzmem.h | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h +index b83b63a0c049b..e1e26dc4180e7 100644 +--- a/include/linux/firmware/qcom/qcom_tzmem.h ++++ b/include/linux/firmware/qcom/qcom_tzmem.h +@@ -17,11 +17,20 @@ struct qcom_tzmem_pool; + * enum qcom_tzmem_policy - Policy for pool growth. + */ + enum qcom_tzmem_policy { +- /**< Static pool, never grow above initial size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_STATIC: Static pool, ++ * never grow above initial size. ++ */ + QCOM_TZMEM_POLICY_STATIC = 1, +- /**< When out of memory, add increment * current size of memory. */ ++ /** ++ * @QCOM_TZMEM_POLICY_MULTIPLIER: When out of memory, ++ * add increment * current size of memory. ++ */ + QCOM_TZMEM_POLICY_MULTIPLIER, +- /**< When out of memory add as much as is needed until max_size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_ON_DEMAND: When out of memory ++ * add as much as is needed until max_size. ++ */ + QCOM_TZMEM_POLICY_ON_DEMAND, + }; + +-- +2.51.0 + diff --git a/queue-6.17/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch b/queue-6.17/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch new file mode 100644 index 0000000000..9ab607d143 --- /dev/null +++ b/queue-6.17/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch @@ -0,0 +1,40 @@ +From 708e5827e28fbd5eec8169b6dbcbc6d744501f93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:58:13 -0600 +Subject: firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc + +From: Dinh Nguyen + +[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ] + +Fix this warning that was generated from "make htmldocs": + +WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' +not described in 'stratix10_svc' + +Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ +Signed-off-by: Dinh Nguyen +Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/stratix10-svc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index 00f58e27f6de5..deee0e7be34bd 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -52,6 +52,7 @@ struct stratix10_svc_chan; + /** + * struct stratix10_svc - svc private data + * @stratix10_svc_rsu: pointer to stratix10 RSU device ++ * @intel_svc_fcs: pointer to the FCS device + */ + struct stratix10_svc { + struct platform_device *stratix10_svc_rsu; +-- +2.51.0 + diff --git a/queue-6.17/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch b/queue-6.17/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch new file mode 100644 index 0000000000..7f746af9c8 --- /dev/null +++ b/queue-6.17/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch @@ -0,0 +1,100 @@ +From 320ad77289316fa5f021f41572ee4f0a4837f0b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 13:44:56 +0100 +Subject: firmware: ti_sci: Set IO Isolation only if the firmware is capable + +From: Thomas Richard (TI.com) + +[ Upstream commit 999e9bc953e321651d69556fdd5dfd178f96f128 ] + +Prevent calling ti_sci_cmd_set_io_isolation() on firmware +that does not support the IO_ISOLATION capability. Add the +MSG_FLAG_CAPS_IO_ISOLATION capability flag and check it before +attempting to set IO isolation during suspend/resume operations. + +Without this check, systems with older firmware may experience +undefined behavior or errors when entering/exiting suspend states. + +Fixes: ec24643bdd62 ("firmware: ti_sci: Add system suspend and resume call") +Signed-off-by: Thomas Richard (TI.com) +Reviewed-by: Kevin Hilman +Link: https://patch.msgid.link/20251031-ti-sci-io-isolation-v2-1-60d826b65949@bootlin.com +Signed-off-by: Nishanth Menon +Signed-off-by: Sasha Levin +--- + drivers/firmware/ti_sci.c | 21 +++++++++++++-------- + drivers/firmware/ti_sci.h | 2 ++ + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index 49fd2ae01055d..8d96a3c12b36a 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -3751,9 +3751,11 @@ static int __maybe_unused ti_sci_suspend_noirq(struct device *dev) + struct ti_sci_info *info = dev_get_drvdata(dev); + int ret = 0; + +- ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); +- if (ret) +- return ret; ++ if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { ++ ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); ++ if (ret) ++ return ret; ++ } + + return 0; + } +@@ -3767,9 +3769,11 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev) + u8 pin; + u8 mode; + +- ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); +- if (ret) +- return ret; ++ if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { ++ ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); ++ if (ret) ++ return ret; ++ } + + ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode); + /* Do not fail to resume on error as the wake reason is not critical */ +@@ -3928,11 +3932,12 @@ static int ti_sci_probe(struct platform_device *pdev) + } + + ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); +- dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s\n", ++ dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n", + info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", +- info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "" ++ info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", ++ info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "" + ); + + ti_sci_setup_ops(info); +diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h +index 701c416b2e78f..7559cde17b6cc 100644 +--- a/drivers/firmware/ti_sci.h ++++ b/drivers/firmware/ti_sci.h +@@ -149,6 +149,7 @@ struct ti_sci_msg_req_reboot { + * MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM + * MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM + * MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM ++ * MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support + * + * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS + * providing currently available SOC/firmware capabilities. SoC that don't +@@ -160,6 +161,7 @@ struct ti_sci_msg_resp_query_fw_caps { + #define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4) + #define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5) + #define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9) ++#define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) + #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) + u64 fw_caps; + } __packed; +-- +2.51.0 + diff --git a/queue-6.17/firmware_loader-make-rust_fw_loader_abstractions-sel.patch b/queue-6.17/firmware_loader-make-rust_fw_loader_abstractions-sel.patch new file mode 100644 index 0000000000..cfe67d2a3a --- /dev/null +++ b/queue-6.17/firmware_loader-make-rust_fw_loader_abstractions-sel.patch @@ -0,0 +1,38 @@ +From ee5c13901074c38935b5fac72dc11e66b6e120b8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 11:40:54 +0900 +Subject: firmware_loader: make RUST_FW_LOADER_ABSTRACTIONS select FW_LOADER + +From: Alexandre Courbot + +[ Upstream commit 9906efa545d1d2cf25a614eeb219d3f8d5a302cd ] + +The use of firmware_loader is an implementation detail of drivers rather +than a dependency. FW_LOADER is typically selected rather than depended +on; the Rust abstractions should do the same thing. + +Fixes: de6582833db0 ("rust: add firmware abstractions") +Signed-off-by: Alexandre Courbot +Link: https://patch.msgid.link/20251106-b4-select-rust-fw-v3-1-771172257755@nvidia.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/base/firmware_loader/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig +index 752b9a9bea038..15eff8a4b5053 100644 +--- a/drivers/base/firmware_loader/Kconfig ++++ b/drivers/base/firmware_loader/Kconfig +@@ -38,7 +38,7 @@ config FW_LOADER_DEBUG + config RUST_FW_LOADER_ABSTRACTIONS + bool "Rust Firmware Loader abstractions" + depends on RUST +- depends on FW_LOADER=y ++ select FW_LOADER + help + This enables the Rust abstractions for the firmware loader API. + +-- +2.51.0 + diff --git a/queue-6.17/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch b/queue-6.17/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch new file mode 100644 index 0000000000..c4b010e499 --- /dev/null +++ b/queue-6.17/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch @@ -0,0 +1,104 @@ +From 65fa8b454d17f164eec4b7fa24ae5ae59a6bd834 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 23:56:30 +0000 +Subject: fs/9p: Don't open remote file with APPEND mode when writeback cache + is used + +From: Tingmao Wang + +[ Upstream commit a63dd8fd137933551bfd9aeeeaa942f04c7aad65 ] + +When page cache is used, writebacks are done on a page granularity, and it +is expected that the underlying filesystem (such as v9fs) should respect +the write position. However, currently v9fs will passthrough O_APPEND to +the server even on cached mode. This causes data corruption if a sync or +fstat gets between two writes to the same file. + +This patch removes the APPEND flag from the open request we send to the +server when writeback caching is involved. I believe keeping server-side +APPEND is probably fine for uncached mode (even if two fds are opened, one +without O_APPEND and one with it, this should still be fine since they +would use separate fid for the writes). + +Signed-off-by: Tingmao Wang +Fixes: 4eb3117888a9 ("fs/9p: Rework cache modes and add new options to Documentation") +Message-ID: <20251102235631.8724-1-m@maowtm.org> +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/vfs_file.c | 11 ++++++++--- + fs/9p/vfs_inode.c | 3 +-- + fs/9p/vfs_inode_dotl.c | 2 +- + 3 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c +index eb0b083da269b..d1db03093d4c3 100644 +--- a/fs/9p/vfs_file.c ++++ b/fs/9p/vfs_file.c +@@ -43,14 +43,18 @@ int v9fs_file_open(struct inode *inode, struct file *file) + struct v9fs_session_info *v9ses; + struct p9_fid *fid; + int omode; ++ int o_append; + + p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); + v9ses = v9fs_inode2v9ses(inode); +- if (v9fs_proto_dotl(v9ses)) ++ if (v9fs_proto_dotl(v9ses)) { + omode = v9fs_open_to_dotl_flags(file->f_flags); +- else ++ o_append = P9_DOTL_APPEND; ++ } else { + omode = v9fs_uflags2omode(file->f_flags, + v9fs_proto_dotu(v9ses)); ++ o_append = P9_OAPPEND; ++ } + fid = file->private_data; + if (!fid) { + fid = v9fs_fid_clone(file_dentry(file)); +@@ -58,9 +62,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) + return PTR_ERR(fid); + + if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { +- int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; ++ int writeback_omode = (omode & ~(P9_OWRITE | o_append)) | P9_ORDWR; + + p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); ++ + err = p9_client_open(fid, writeback_omode); + if (err < 0) { + p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index 399d455d50d62..2fe2d1cb20ff1 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -790,7 +790,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, + p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_OAPPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +@@ -1403,4 +1403,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = { + .getattr = v9fs_vfs_getattr, + .setattr = v9fs_vfs_setattr, + }; +- +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index 5b5fda617b805..a84ee2a04dbbd 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -286,7 +286,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, + } + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_DOTL_APPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +-- +2.51.0 + diff --git a/queue-6.17/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-6.17/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..dec7051887 --- /dev/null +++ b/queue-6.17/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From dfb1b96d1eae6db7fd5200d2b49726ac2e0e0108 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 8f9fe1d7a6908..a557e3ec0d4c4 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1015,9 +1015,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-6.17/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-6.17/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..8761f6f59f --- /dev/null +++ b/queue-6.17/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From 89b28498247533aaa34806ee77d655e3d8b2fcff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index a557e3ec0d4c4..e5a005d216f31 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -325,8 +325,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.17/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch b/queue-6.17/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch new file mode 100644 index 0000000000..703b630365 --- /dev/null +++ b/queue-6.17/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch @@ -0,0 +1,83 @@ +From 79e911d34a734d865aad8660c64888a2fb469d59 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Oct 2025 02:38:43 -0400 +Subject: fuse_ctl_add_conn(): fix nlink breakage in case of early failure + +From: Al Viro + +[ Upstream commit c460192aae197df1b4db1dca493c35ad529f1b64 ] + +fuse_ctl_remove_conn() used to decrement the link count of root +manually; that got subsumed by simple_recursive_removal(), but +in case when subdirectory creation has failed the latter won't +get called. + +Just move the modification of parent's link count into +fuse_ctl_add_dentry() to keep the things simple. Allows to +get rid of the nlink argument as well... + +Fixes: fcaac5b42768 "fuse_ctl: use simple_recursive_removal()" +Acked-by: Miklos Szeredi +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/fuse/control.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/fs/fuse/control.c b/fs/fuse/control.c +index bb407705603c2..5247df896c5d0 100644 +--- a/fs/fuse/control.c ++++ b/fs/fuse/control.c +@@ -205,8 +205,7 @@ static const struct file_operations fuse_conn_congestion_threshold_ops = { + + static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, + struct fuse_conn *fc, +- const char *name, +- int mode, int nlink, ++ const char *name, int mode, + const struct inode_operations *iop, + const struct file_operations *fop) + { +@@ -232,7 +231,10 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, + if (iop) + inode->i_op = iop; + inode->i_fop = fop; +- set_nlink(inode, nlink); ++ if (S_ISDIR(mode)) { ++ inc_nlink(d_inode(parent)); ++ inc_nlink(inode); ++ } + inode->i_private = fc; + d_add(dentry, inode); + +@@ -252,22 +254,21 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) + return 0; + + parent = fuse_control_sb->s_root; +- inc_nlink(d_inode(parent)); + sprintf(name, "%u", fc->dev); +- parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2, ++ parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, + &simple_dir_inode_operations, + &simple_dir_operations); + if (!parent) + goto err; + +- if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1, ++ if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, + NULL, &fuse_ctl_waiting_ops) || +- !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1, ++ !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, + NULL, &fuse_ctl_abort_ops) || + !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600, +- 1, NULL, &fuse_conn_max_background_ops) || ++ NULL, &fuse_conn_max_background_ops) || + !fuse_ctl_add_dentry(parent, fc, "congestion_threshold", +- S_IFREG | 0600, 1, NULL, ++ S_IFREG | 0600, NULL, + &fuse_conn_congestion_threshold_ops)) + goto err; + +-- +2.51.0 + diff --git a/queue-6.17/gfs2-prevent-recursive-memory-reclaim.patch b/queue-6.17/gfs2-prevent-recursive-memory-reclaim.patch new file mode 100644 index 0000000000..85c92d8d4f --- /dev/null +++ b/queue-6.17/gfs2-prevent-recursive-memory-reclaim.patch @@ -0,0 +1,135 @@ +From f4e5d4403ba9a25de48bf064a21a5fab7bf5c405 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:05:37 +0000 +Subject: gfs2: Prevent recursive memory reclaim + +From: Andreas Gruenbacher + +[ Upstream commit 2c5f4a53476e3cab70adc77b38942c066bd2c17c ] + +Function new_inode() returns a new inode with inode->i_mapping->gfp_mask +set to GFP_HIGHUSER_MOVABLE. This value includes the __GFP_FS flag, so +allocations in that address space can recurse into filesystem memory +reclaim. We don't want that to happen because it can consume a +significant amount of stack memory. + +Worse than that is that it can also deadlock: for example, in several +places, gfs2_unstuff_dinode() is called inside filesystem transactions. +This calls filemap_grab_folio(), which can allocate a new folio, which +can trigger memory reclaim. If memory reclaim recurses into the +filesystem and starts another transaction, a deadlock will ensue. + +To fix these kinds of problems, prevent memory reclaim from recursing +into filesystem code by making sure that the gfp_mask of inode address +spaces doesn't include __GFP_FS. + +The "meta" and resource group address spaces were already using GFP_NOFS +as their gfp_mask (which doesn't include __GFP_FS). The default value +of GFP_HIGHUSER_MOVABLE is less restrictive than GFP_NOFS, though. To +avoid being overly limiting, use the default value and only knock off +the __GFP_FS flag. I'm not sure if this will actually make a +difference, but it also shouldn't hurt. + +This patch is loosely based on commit ad22c7a043c2 ("xfs: prevent stack +overflows from page cache allocation"). + +Fixes xfstest generic/273. + +Fixes: dc0b9435238c ("gfs: Don't use GFP_NOFS in gfs2_unstuff_dinode") +Reviewed-by: Andrew Price +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glock.c | 5 ++++- + fs/gfs2/inode.c | 15 +++++++++++++++ + fs/gfs2/inode.h | 1 + + fs/gfs2/ops_fstype.c | 2 +- + 4 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index a6535413a0b46..d00cedf4460cd 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -1205,10 +1205,13 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, + + mapping = gfs2_glock2aspace(gl); + if (mapping) { ++ gfp_t gfp_mask; ++ + mapping->a_ops = &gfs2_meta_aops; + mapping->host = sdp->sd_inode; + mapping->flags = 0; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfp_mask = mapping_gfp_mask(sdp->sd_inode->i_mapping); ++ mapping_set_gfp_mask(mapping, gfp_mask); + mapping->i_private_data = NULL; + mapping->writeback_index = 0; + } +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 8760e7e20c9d8..35c1ccc1747f3 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -89,6 +89,19 @@ static int iget_set(struct inode *inode, void *opaque) + return 0; + } + ++void gfs2_setup_inode(struct inode *inode) ++{ ++ gfp_t gfp_mask; ++ ++ /* ++ * Ensure all page cache allocations are done from GFP_NOFS context to ++ * prevent direct reclaim recursion back into the filesystem and blowing ++ * stacks or deadlocking. ++ */ ++ gfp_mask = mapping_gfp_mask(inode->i_mapping); ++ mapping_set_gfp_mask(inode->i_mapping, gfp_mask & ~__GFP_FS); ++} ++ + /** + * gfs2_inode_lookup - Lookup an inode + * @sb: The super block +@@ -132,6 +145,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, + struct gfs2_glock *io_gl; + int extra_flags = 0; + ++ gfs2_setup_inode(inode); + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, + &ip->i_gl); + if (unlikely(error)) +@@ -752,6 +766,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, + error = -ENOMEM; + if (!inode) + goto fail_gunlock; ++ gfs2_setup_inode(inode); + ip = GFS2_I(inode); + + error = posix_acl_create(dir, &mode, &default_acl, &acl); +diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h +index e43f08eb26e72..2fcd96dd13613 100644 +--- a/fs/gfs2/inode.h ++++ b/fs/gfs2/inode.h +@@ -86,6 +86,7 @@ static inline int gfs2_check_internal_file_size(struct inode *inode, + return -EIO; + } + ++void gfs2_setup_inode(struct inode *inode); + struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, + u64 no_addr, u64 no_formal_ino, + unsigned int blktype); +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index efe99b7325513..468ff57386dc3 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -1183,7 +1183,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) + + mapping = gfs2_aspace(sdp); + mapping->a_ops = &gfs2_rgrp_aops; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfs2_setup_inode(sdp->sd_inode); + + error = init_names(sdp, silent); + if (error) +-- +2.51.0 + diff --git a/queue-6.17/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-6.17/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..61b47efa58 --- /dev/null +++ b/queue-6.17/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 998444b0f2e986fa064ba60ff4602b741acf20fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index f63d14a57a1d9..acc7d82e0585e 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -345,8 +345,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -369,7 +367,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-6.17/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch b/queue-6.17/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch new file mode 100644 index 0000000000..9168fa2a78 --- /dev/null +++ b/queue-6.17/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch @@ -0,0 +1,66 @@ +From 7c208a8de52bd0380a7a0c7a63f649256427b0c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:40:27 +0800 +Subject: greybus: gb-beagleplay: Fix timeout handling in bootloader functions + +From: Haotian Zhang + +[ Upstream commit e6df0f649cff08da7a2feb6d963b39076ca129f9 ] + +wait_for_completion_timeout() returns the remaining jiffies +(at least 1) on success or 0 on timeout, but never negative +error codes. The current code incorrectly checks for negative +values, causing timeouts to be ignored and treated as success. + +Check for a zero return value to correctly identify and +handle timeout events. + +Fixes: 0cf7befa3ea2 ("greybus: gb-beagleplay: Add firmware upload API") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251121064027.571-1-vulab@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/greybus/gb-beagleplay.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c +index 9610f878da1b6..87186f891a6ac 100644 +--- a/drivers/greybus/gb-beagleplay.c ++++ b/drivers/greybus/gb-beagleplay.c +@@ -644,8 +644,8 @@ static int cc1352_bootloader_wait_for_ack(struct gb_beagleplay *bg) + + ret = wait_for_completion_timeout( + &bg->fwl_ack_com, msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire ack semaphore"); + + switch (READ_ONCE(bg->fwl_ack)) { +@@ -683,8 +683,8 @@ static int cc1352_bootloader_get_status(struct gb_beagleplay *bg) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + switch (READ_ONCE(bg->fwl_cmd_response)) { +@@ -768,8 +768,8 @@ static int cc1352_bootloader_crc32(struct gb_beagleplay *bg, u32 *crc32) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + *crc32 = READ_ONCE(bg->fwl_cmd_response); +-- +2.51.0 + diff --git a/queue-6.17/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch b/queue-6.17/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch new file mode 100644 index 0000000000..119d6f5c99 --- /dev/null +++ b/queue-6.17/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch @@ -0,0 +1,59 @@ +From 34c0cc6c2787c80bb3388413832c4ddf0f7da289 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 19:30:58 +0000 +Subject: HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync() + +From: Mavroudis Chatzilazaridis + +[ Upstream commit aba7963544d47d82cdf36602a6678a093af0299d ] + +Currently, hidpp_send_message_sync() retries sending the message when the +device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which +has a different meaning under RAP. This ends up being a problem because +this function is used for both FAP and RAP messages. + +This issue is not noticeable on older receivers with unreachable devices +since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to +HIDPP20_ERROR_BUSY (0x08). + +However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which +happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when +the device is not actually busy. + +This is resolved by checking if the error response is FAP or RAP and +picking the respective ERROR_BUSY code. + +Fixes: 60165ab774cb ("HID: logitech-hidpp: rework one more time the retries attempts") +Signed-off-by: Mavroudis Chatzilazaridis +Tested-by: Stuart Hayhurst +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 5e763de4b94fd..a88f2e5f791c6 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -352,10 +352,15 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, + + do { + ret = __do_hidpp_send_message_sync(hidpp, message, response); +- if (ret != HIDPP20_ERROR_BUSY) ++ if (response->report_id == REPORT_ID_HIDPP_SHORT && ++ ret != HIDPP_ERROR_BUSY) ++ break; ++ if ((response->report_id == REPORT_ID_HIDPP_LONG || ++ response->report_id == REPORT_ID_HIDPP_VERY_LONG) && ++ ret != HIDPP20_ERROR_BUSY) + break; + +- dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret); ++ dbg_hid("%s:got busy hidpp error %02X, retrying\n", __func__, ret); + } while (--max_retries); + + mutex_unlock(&hidpp->send_mutex); +-- +2.51.0 + diff --git a/queue-6.17/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch b/queue-6.17/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch new file mode 100644 index 0000000000..c7dca02464 --- /dev/null +++ b/queue-6.17/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch @@ -0,0 +1,54 @@ +From 4bd6e10ea2d77016ae07e204e1f31212161b797c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 00:26:02 +0800 +Subject: hwmon: sy7636a: Fix regulator_enable resource leak on error path + +From: Haotian Zhang + +[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ] + +In sy7636a_sensor_probe(), regulator_enable() is called but if +devm_hwmon_device_register_with_info() fails, the function returns +without calling regulator_disable(), leaving the regulator enabled +and leaking the reference count. + +Switch to devm_regulator_get_enable() to automatically +manage the regulator resource. + +Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sy7636a-hwmon.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c +index a12fc0ce70e76..d51daaf63d632 100644 +--- a/drivers/hwmon/sy7636a-hwmon.c ++++ b/drivers/hwmon/sy7636a-hwmon.c +@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { + static int sy7636a_sensor_probe(struct platform_device *pdev) + { + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); +- struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + +- regulator = devm_regulator_get(&pdev->dev, "vcom"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); ++ err = devm_regulator_get_enable(&pdev->dev, "vcom"); + if (err) + return err; + +-- +2.51.0 + diff --git a/queue-6.17/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-6.17/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..479d904f46 --- /dev/null +++ b/queue-6.17/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From 7be37396fa8da824c2e437b553e6f50fc00d7e36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 67a18e437f831..08caaad195d59 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2811,10 +2811,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2822,6 +2818,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.17/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-6.17/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..34ae10a6e1 --- /dev/null +++ b/queue-6.17/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From 05edc09feed78e1941153a693b2d8b3f55b0cec7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index 9641e66a4e5f2..e70a64f2a32fa 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -406,21 +406,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-6.17/iavf-implement-settime64-with-eopnotsupp.patch b/queue-6.17/iavf-implement-settime64-with-eopnotsupp.patch new file mode 100644 index 0000000000..70ea88abdb --- /dev/null +++ b/queue-6.17/iavf-implement-settime64-with-eopnotsupp.patch @@ -0,0 +1,54 @@ +From 0c62050394ce52f0cb2884365f9cf7112e29ba9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:48:49 +0100 +Subject: iavf: Implement settime64 with -EOPNOTSUPP + +From: Michal Schmidt + +[ Upstream commit 1e43ebcd5152b3e681a334cc6542fb21770c3a2e ] + +ptp_clock_settime() assumes every ptp_clock has implemented settime64(). +Stub it with -EOPNOTSUPP to prevent a NULL dereference. + +The fix is similar to commit 329d050bbe63 ("gve: Implement settime64 +with -EOPNOTSUPP"). + +Fixes: d734223b2f0d ("iavf: add initial framework for registering PTP clock") +Signed-off-by: Michal Schmidt +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Tim Hostetler +Link: https://patch.msgid.link/20251126094850.2842557-1-mschmidt@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/iavf/iavf_ptp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.c b/drivers/net/ethernet/intel/iavf/iavf_ptp.c +index b4d5eda2e84fc..9cbd8c1540318 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ptp.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.c +@@ -252,6 +252,12 @@ static int iavf_ptp_gettimex64(struct ptp_clock_info *info, + return iavf_read_phc_indirect(adapter, ts, sts); + } + ++static int iavf_ptp_settime64(struct ptp_clock_info *info, ++ const struct timespec64 *ts) ++{ ++ return -EOPNOTSUPP; ++} ++ + /** + * iavf_ptp_cache_phc_time - Cache PHC time for performing timestamp extension + * @adapter: private adapter structure +@@ -320,6 +326,7 @@ static int iavf_ptp_register_clock(struct iavf_adapter *adapter) + KBUILD_MODNAME, dev_name(dev)); + ptp_info->owner = THIS_MODULE; + ptp_info->gettimex64 = iavf_ptp_gettimex64; ++ ptp_info->settime64 = iavf_ptp_settime64; + ptp_info->do_aux_work = iavf_ptp_do_aux_work; + + clock = ptp_clock_register(ptp_info, dev); +-- +2.51.0 + diff --git a/queue-6.17/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch b/queue-6.17/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch new file mode 100644 index 0000000000..d020f8cde8 --- /dev/null +++ b/queue-6.17/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch @@ -0,0 +1,38 @@ +From 85400ecabc058b602f893f91ae353e98a7a3d438 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 19:30:18 -0300 +Subject: iio: imu: bmi270: fix dev_err_probe error msg + +From: Rodrigo Gobbi + +[ Upstream commit 02f86101e430cce9a99a044b483c4ed5b91bb3b8 ] + +The bmi270 can be connected to I2C or a SPI interface. If it is a SPI, +during probe, if devm_regmap_init() fails, it should print the "spi" +term rather "i2c". + +Fixes: 92cc50a00574 ("iio: imu: bmi270: Add spi driver for bmi270 imu") +Signed-off-by: Rodrigo Gobbi +Reviewed-by: Andy Shevchenko +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/bmi270/bmi270_spi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/bmi270/bmi270_spi.c b/drivers/iio/imu/bmi270/bmi270_spi.c +index 19dd7734f9d07..80c9fa1d685ab 100644 +--- a/drivers/iio/imu/bmi270/bmi270_spi.c ++++ b/drivers/iio/imu/bmi270/bmi270_spi.c +@@ -60,7 +60,7 @@ static int bmi270_spi_probe(struct spi_device *spi) + &bmi270_spi_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), +- "Failed to init i2c regmap"); ++ "Failed to init spi regmap\n"); + + return bmi270_core_probe(dev, regmap, chip_info); + } +-- +2.51.0 + diff --git a/queue-6.17/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-6.17/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..3fb3173d63 --- /dev/null +++ b/queue-6.17/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From fcc9fadccf6b8ff844dea21b8ecd6e82a07ae227 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 381b016fa5243..56244d49ab2fc 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -383,7 +383,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-6.17/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch b/queue-6.17/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch new file mode 100644 index 0000000000..4e3c114e53 --- /dev/null +++ b/queue-6.17/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch @@ -0,0 +1,134 @@ +From a8d054e4db85cf63abf728404eb15f3ca32c8182 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 13:35:03 +0200 +Subject: ima: Attach CREDS_CHECK IMA hook to bprm_creds_from_file LSM hook + +From: Roberto Sassu + +[ Upstream commit 8f3fc4f3f8aa6e99266c69cc78bdaa58379e65fc ] + +Since commit 56305aa9b6fa ("exec: Compute file based creds only once"), the +credentials to be applied to the process after execution are not calculated +anymore for each step of finding intermediate interpreters (including the +final binary), but only after the final binary to be executed without +interpreter has been found. + +In particular, that means that the bprm_check_security LSM hook will not +see the updated cred->e[ug]id for the intermediate and for the final binary +to be executed, since the function doing this task has been moved from +prepare_binprm(), which calls the bprm_check_security hook, to +bprm_creds_from_file(). + +This breaks the IMA expectation for the CREDS_CHECK hook, introduced with +commit d906c10d8a31 ("IMA: Support using new creds in appraisal policy"), +which expects to evaluate "the credentials that will be committed when the +new process is started". This is clearly not the case for the CREDS_CHECK +IMA hook, which is attached to bprm_check_security. + +This issue does not affect systems which load a policy with the BPRM_CHECK +hook with no other criteria, as is the case with the built-in "tcb" and/or +"appraise_tcb" IMA policies. The "tcb" built-in policy measures all +executions regardless of the new credentials, and the "appraise_tcb" policy +is written in terms of the file owner, rather than IMA hooks. + +However, it does affect systems without a BPRM_CHECK policy rule or with a +BPRM_CHECK policy rule that does not include what CREDS_CHECK evaluates. As +an extreme example, taking a standalone rule like: + +measure func=CREDS_CHECK euid=0 + +This will not measure for example sudo (because CREDS_CHECK still sees the +bprm->cred->euid set to the regular user UID), but only the subsequent +commands after the euid was applied to the children. + +Make set[ug]id programs measured/appraised again by splitting +ima_bprm_check() in two separate hook implementations (CREDS_CHECK now +being implemented by ima_creds_check()), and by attaching CREDS_CHECK to +the bprm_creds_from_file LSM hook. + +The limitation of this approach is that CREDS_CHECK will not be invoked +anymore for the intermediate interpreters, like it was before, but only for +the final binary. This limitation can be removed only by reverting commit +56305aa9b6fa ("exec: Compute file based creds only once"). + +Link: https://github.com/linux-integrity/linux/issues/3 +Fixes: 56305aa9b6fa ("exec: Compute file based creds only once") +Cc: Serge E. Hallyn +Cc: Matthew Garrett +Cc: Eric W. Biederman +Cc: Jann Horn +Cc: Christian Brauner +Cc: Kees Cook +Signed-off-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_main.c | 42 ++++++++++++++++++++++++------- + 1 file changed, 33 insertions(+), 9 deletions(-) + +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index cdd225f65a629..ebaebccfbe9ab 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -573,18 +573,41 @@ static int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, + */ + static int ima_bprm_check(struct linux_binprm *bprm) + { +- int ret; + struct lsm_prop prop; + + security_current_getlsmprop_subj(&prop); +- ret = process_measurement(bprm->file, current_cred(), +- &prop, NULL, 0, MAY_EXEC, BPRM_CHECK); +- if (ret) +- return ret; +- +- security_cred_getlsmprop(bprm->cred, &prop); +- return process_measurement(bprm->file, bprm->cred, &prop, NULL, 0, +- MAY_EXEC, CREDS_CHECK); ++ return process_measurement(bprm->file, current_cred(), ++ &prop, NULL, 0, MAY_EXEC, BPRM_CHECK); ++} ++ ++/** ++ * ima_creds_check - based on policy, collect/store measurement. ++ * @bprm: contains the linux_binprm structure ++ * @file: contains the file descriptor of the binary being executed ++ * ++ * The OS protects against an executable file, already open for write, ++ * from being executed in deny_write_access() and an executable file, ++ * already open for execute, from being modified in get_write_access(). ++ * So we can be certain that what we verify and measure here is actually ++ * what is being executed. ++ * ++ * The difference from ima_bprm_check() is that ima_creds_check() is invoked ++ * only after determining the final binary to be executed without interpreter, ++ * and not when searching for intermediate binaries. The reason is that since ++ * commit 56305aa9b6fab ("exec: Compute file based creds only once"), the ++ * credentials to be applied to the process are calculated only at that stage ++ * (bprm_creds_from_file security hook instead of bprm_check_security). ++ * ++ * On success return 0. On integrity appraisal error, assuming the file ++ * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. ++ */ ++static int ima_creds_check(struct linux_binprm *bprm, const struct file *file) ++{ ++ struct lsm_prop prop; ++ ++ security_current_getlsmprop_subj(&prop); ++ return process_measurement((struct file *)file, bprm->cred, &prop, NULL, ++ 0, MAY_EXEC, CREDS_CHECK); + } + + /** +@@ -1242,6 +1265,7 @@ static int __init init_ima(void) + static struct security_hook_list ima_hooks[] __ro_after_init = { + LSM_HOOK_INIT(bprm_check_security, ima_bprm_check), + LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec), ++ LSM_HOOK_INIT(bprm_creds_from_file, ima_creds_check), + LSM_HOOK_INIT(file_post_open, ima_file_check), + LSM_HOOK_INIT(inode_post_create_tmpfile, ima_post_create_tmpfile), + LSM_HOOK_INIT(file_release, ima_file_free), +-- +2.51.0 + diff --git a/queue-6.17/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-6.17/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..db29340786 --- /dev/null +++ b/queue-6.17/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From 9fc91ebeeb0d3e922059ed14411822822351565f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 128fab8979308..db6d55af5a80b 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -674,7 +674,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..6036d0fd28 --- /dev/null +++ b/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From 60970a528995b62b4a57d37447231af675e29682 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index 57c0df29ee964..5ab31eb69acb4 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -850,6 +850,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 4316c127f7896..ddeb5ee52d404 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -720,8 +720,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -730,6 +733,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch b/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch new file mode 100644 index 0000000000..bac1973080 --- /dev/null +++ b/queue-6.17/inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch @@ -0,0 +1,117 @@ +From 1fc578d9d931d468965ff86594c9fe2f5d51310e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:36 +0800 +Subject: inet: Avoid ehash lookup race in inet_twsk_hashdance_schedule() + +From: Xuanqiang Luo + +[ Upstream commit b8ec80b130211e7bf076ef72365952979d5f7a72 ] + +Since ehash lookups are lockless, if another CPU is converting sk to tw +concurrently, fetching the newly inserted tw with tw->tw_refcnt == 0 cause +lookup failure. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_twsk_hashdance_schedule() + spin_lock() + inet_twsk_add_node_rcu(tw, ...) +__inet_lookup_established() +(find tw, failure due to tw_refcnt = 0) + __sk_nulls_del_node_init_rcu(sk) + refcount_set(&tw->tw_refcnt, 3) + spin_unlock() + +By replacing sk with tw atomically via hlist_nulls_replace_init_rcu() after +setting tw_refcnt, we ensure that tw is either fully initialized or not +visible to other CPUs, eliminating the race. + +It's worth noting that we held lock_sock() before the replacement, so +there's no need to check if sk is hashed. Thanks to Kuniyuki Iwashima! + +Fixes: 3ab5aee7fe84 ("net: Convert TCP & DCCP hash tables to use RCU / hlist_nulls") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-4-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/inet_timewait_sock.c | 35 ++++++++++++----------------------- + 1 file changed, 12 insertions(+), 23 deletions(-) + +diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c +index 6fb9efdbee27a..2386552f4eee3 100644 +--- a/net/ipv4/inet_timewait_sock.c ++++ b/net/ipv4/inet_timewait_sock.c +@@ -86,12 +86,6 @@ void inet_twsk_put(struct inet_timewait_sock *tw) + } + EXPORT_SYMBOL_GPL(inet_twsk_put); + +-static void inet_twsk_add_node_rcu(struct inet_timewait_sock *tw, +- struct hlist_nulls_head *list) +-{ +- hlist_nulls_add_head_rcu(&tw->tw_node, list); +-} +- + static void inet_twsk_schedule(struct inet_timewait_sock *tw, int timeo) + { + __inet_twsk_schedule(tw, timeo, false); +@@ -111,13 +105,12 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + { + const struct inet_sock *inet = inet_sk(sk); + const struct inet_connection_sock *icsk = inet_csk(sk); +- struct inet_ehash_bucket *ehead = inet_ehash_bucket(hashinfo, sk->sk_hash); + spinlock_t *lock = inet_ehash_lockp(hashinfo, sk->sk_hash); + struct inet_bind_hashbucket *bhead, *bhead2; + +- /* Step 1: Put TW into bind hash. Original socket stays there too. +- Note, that any socket with inet->num != 0 MUST be bound in +- binding cache, even if it is closed. ++ /* Put TW into bind hash. Original socket stays there too. ++ * Note, that any socket with inet->num != 0 MUST be bound in ++ * binding cache, even if it is closed. + */ + bhead = &hashinfo->bhash[inet_bhashfn(twsk_net(tw), inet->inet_num, + hashinfo->bhash_size)]; +@@ -139,19 +132,6 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + + spin_lock(lock); + +- /* Step 2: Hash TW into tcp ehash chain */ +- inet_twsk_add_node_rcu(tw, &ehead->chain); +- +- /* Step 3: Remove SK from hash chain */ +- if (__sk_nulls_del_node_init_rcu(sk)) +- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); +- +- +- /* Ensure above writes are committed into memory before updating the +- * refcount. +- * Provides ordering vs later refcount_inc(). +- */ +- smp_wmb(); + /* tw_refcnt is set to 3 because we have : + * - one reference for bhash chain. + * - one reference for ehash chain. +@@ -161,6 +141,15 @@ void inet_twsk_hashdance_schedule(struct inet_timewait_sock *tw, + */ + refcount_set(&tw->tw_refcnt, 3); + ++ /* Ensure tw_refcnt has been set before tw is published. ++ * smp_wmb() provides the necessary memory barrier to enforce this ++ * ordering. ++ */ ++ smp_wmb(); ++ ++ hlist_nulls_replace_init_rcu(&sk->sk_nulls_node, &tw->tw_node); ++ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ + inet_twsk_schedule(tw, timeo); + + spin_unlock(lock); +-- +2.51.0 + diff --git a/queue-6.17/interconnect-debugfs-fix-incorrect-error-handling-fo.patch b/queue-6.17/interconnect-debugfs-fix-incorrect-error-handling-fo.patch new file mode 100644 index 0000000000..0db2f0fca9 --- /dev/null +++ b/queue-6.17/interconnect-debugfs-fix-incorrect-error-handling-fo.patch @@ -0,0 +1,53 @@ +From e83459bf596a73a17b8c72ded08b923fd416e4a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 23:14:47 +0800 +Subject: interconnect: debugfs: Fix incorrect error handling for NULL path + +From: Kuan-Wei Chiu + +[ Upstream commit 6bfe104fd0f94d0248af22c256ce725ee087157b ] + +The icc_commit_set() function, used by the debugfs interface, checks +the validity of the global cur_path pointer using IS_ERR_OR_NULL(). +However, in the specific case where cur_path is NULL, while +IS_ERR_OR_NULL(NULL) correctly evaluates to true, the subsequent call +to PTR_ERR(NULL) returns 0. + +This causes the function to return a success code (0) instead of an +error, misleading the user into believing their bandwidth request was +successfully committed when, in fact, no operation was performed. + +Fix this by adding an explicit check to return -EINVAL if cur_path is +NULL. This prevents silent failures and ensures that an invalid +operational sequence is immediately and clearly reported as an error. + +Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") +Signed-off-by: Kuan-Wei Chiu +Link: https://lore.kernel.org/r/20251010151447.2289779-1-visitorckw@gmail.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/debugfs-client.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c +index bc3fd8a7b9eb4..778deeb4a7e8a 100644 +--- a/drivers/interconnect/debugfs-client.c ++++ b/drivers/interconnect/debugfs-client.c +@@ -117,7 +117,12 @@ static int icc_commit_set(void *data, u64 val) + + mutex_lock(&debugfs_lock); + +- if (IS_ERR_OR_NULL(cur_path)) { ++ if (!cur_path) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (IS_ERR(cur_path)) { + ret = PTR_ERR(cur_path); + goto out; + } +-- +2.51.0 + diff --git a/queue-6.17/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch b/queue-6.17/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch new file mode 100644 index 0000000000..235ecc028c --- /dev/null +++ b/queue-6.17/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch @@ -0,0 +1,38 @@ +From 6858a5a00be899c3dcc92b2793cef33137e43e49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:00 +0300 +Subject: interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS + +From: Dmitry Baryshkov + +[ Upstream commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 ] + +>From the initial submission the interconnect driver missed the link from +SNOC_PNOC to the USB 2 configuration space. Add missing link in order to +let the platform configure and utilize this path. + +Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/msm8996.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c +index b73566c9b21f9..84cfafb22aa17 100644 +--- a/drivers/interconnect/qcom/msm8996.c ++++ b/drivers/interconnect/qcom/msm8996.c +@@ -552,6 +552,7 @@ static struct qcom_icc_node mas_venus_vmem = { + static const u16 mas_snoc_pnoc_links[] = { + MSM8996_SLAVE_BLSP_1, + MSM8996_SLAVE_BLSP_2, ++ MSM8996_SLAVE_USB_HS, + MSM8996_SLAVE_SDCC_1, + MSM8996_SLAVE_SDCC_2, + MSM8996_SLAVE_SDCC_4, +-- +2.51.0 + diff --git a/queue-6.17/io_uring-use-write_once-for-user-shared-memory.patch b/queue-6.17/io_uring-use-write_once-for-user-shared-memory.patch new file mode 100644 index 0000000000..ab4855524a --- /dev/null +++ b/queue-6.17/io_uring-use-write_once-for-user-shared-memory.patch @@ -0,0 +1,52 @@ +From e3665e010fe65fa3f455c20e708c840b192dc5cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 12:58:19 +0000 +Subject: io_uring: use WRITE_ONCE for user shared memory + +From: Pavel Begunkov + +[ Upstream commit 93e197e524b14d185d011813b72773a1a49d932d ] + +IORING_SETUP_NO_MMAP rings remain user accessible even before the ctx +setup is finalised, so use WRITE_ONCE consistently when initialising +rings. + +Fixes: 03d89a2de25bb ("io_uring: support for user allocated memory for rings/sqes") +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 93665cebe9bdd..44afe57cbd653 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -3570,10 +3570,6 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx, + + if (!(ctx->flags & IORING_SETUP_NO_SQARRAY)) + ctx->sq_array = (u32 *)((char *)rings + sq_array_offset); +- rings->sq_ring_mask = p->sq_entries - 1; +- rings->cq_ring_mask = p->cq_entries - 1; +- rings->sq_ring_entries = p->sq_entries; +- rings->cq_ring_entries = p->cq_entries; + + if (p->flags & IORING_SETUP_SQE128) + size = array_size(2 * sizeof(struct io_uring_sqe), p->sq_entries); +@@ -3596,6 +3592,12 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx, + return ret; + } + ctx->sq_sqes = io_region_get_ptr(&ctx->sq_region); ++ ++ memset(rings, 0, sizeof(*rings)); ++ WRITE_ONCE(rings->sq_ring_mask, ctx->sq_entries - 1); ++ WRITE_ONCE(rings->cq_ring_mask, ctx->cq_entries - 1); ++ WRITE_ONCE(rings->sq_ring_entries, ctx->sq_entries); ++ WRITE_ONCE(rings->cq_ring_entries, ctx->cq_entries); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.17/iomap-always-run-error-completions-in-user-context.patch b/queue-6.17/iomap-always-run-error-completions-in-user-context.patch new file mode 100644 index 0000000000..6ac4ee29f6 --- /dev/null +++ b/queue-6.17/iomap-always-run-error-completions-in-user-context.patch @@ -0,0 +1,51 @@ +From 678cdcaeede652db8538fdeca1233392993d645c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:06:27 +0100 +Subject: iomap: always run error completions in user context + +From: Christoph Hellwig + +[ Upstream commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a ] + +At least zonefs expects error completions to be able to sleep. Because +error completions aren't performance critical, just defer them to workqueue +context unconditionally. + +Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251113170633.1453259-3-hch@lst.de +Reviewed-by: Jan Kara +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index 46aa85af13dc5..97c40e7df7215 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -179,7 +179,18 @@ static void iomap_dio_done(struct iomap_dio *dio) + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ return; ++ } ++ ++ /* ++ * Always run error completions in user context. These are not ++ * performance critical and some code relies on taking sleeping locks ++ * for error handling. ++ */ ++ if (dio->error) ++ dio->flags &= ~IOMAP_DIO_INLINE_COMP; ++ ++ if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); + } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { +-- +2.51.0 + diff --git a/queue-6.17/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch b/queue-6.17/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch new file mode 100644 index 0000000000..cc1935c190 --- /dev/null +++ b/queue-6.17/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch @@ -0,0 +1,47 @@ +From 1cd7e87774fee512c1b5e37e09a873def20a4c3c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 22:55:25 -0700 +Subject: iommu/amd: Fix potential out-of-bounds read in iommu_mmio_show + +From: Songtang Liu + +[ Upstream commit a0c7005333f9a968abb058b1d77bbcd7fb7fd1e7 ] + +In iommu_mmio_write(), it validates the user-provided offset with the +check: `iommu->dbg_mmio_offset > iommu->mmio_phys_end - 4`. +This assumes a 4-byte access. However, the corresponding +show handler, iommu_mmio_show(), uses readq() to perform an 8-byte +(64-bit) read. + +If a user provides an offset equal to `mmio_phys_end - 4`, the check +passes, and will lead to a 4-byte out-of-bounds read. + +Fix this by adjusting the boundary check to use sizeof(u64), which +corresponds to the size of the readq() operation. + +Fixes: 7a4ee419e8c1 ("iommu/amd: Add debugfs support to dump IOMMU MMIO registers") +Signed-off-by: Songtang Liu +Reviewed-by: Dheeraj Kumar Srivastava +Tested-by: Dheeraj Kumar Srivastava +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd/debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c +index 10fa217a71199..20b04996441d6 100644 +--- a/drivers/iommu/amd/debugfs.c ++++ b/drivers/iommu/amd/debugfs.c +@@ -37,7 +37,7 @@ static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, + if (ret) + return ret; + +- if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - 4) { ++ if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { + iommu->dbg_mmio_offset = -1; + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.17/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-6.17/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..438d5c6303 --- /dev/null +++ b/queue-6.17/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From eb5c0b5cee845ac6e5136af637f3cc7f9b15f4c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 57c097e876130..c939d0856b719 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -431,17 +431,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -464,6 +466,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-6.17/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch b/queue-6.17/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch new file mode 100644 index 0000000000..950c3a7306 --- /dev/null +++ b/queue-6.17/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch @@ -0,0 +1,46 @@ +From 90c119b9a3ac97ca83bf13938ae52bd889c81a1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 11:09:17 -0800 +Subject: iommu/arm-smmu-v3: Fix error check in arm_smmu_alloc_cd_tables + +From: Ryan Huang + +[ Upstream commit 5941f0e0c1e0be03ebc15b461f64208f5250d3d9 ] + +In arm_smmu_alloc_cd_tables(), the error check following the +dma_alloc_coherent() for cd_table->l2.l1tab incorrectly tests +cd_table->l2.l2ptrs. + +This means an allocation failure for l1tab goes undetected, causing +the function to return 0 (success) erroneously. + +Correct the check to test cd_table->l2.l1tab. + +Fixes: e3b1be2e73db ("iommu/arm-smmu-v3: Reorganize struct arm_smmu_ctx_desc_cfg") +Signed-off-by: Daniel Mentz +Signed-off-by: Ryan Huang +Reviewed-by: Nicolin Chen +Reviewed-by: Pranjal Shrivastava +Reviewed-by: Jason Gunthorpe +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 2a8b46b948f05..9780f40ba3e65 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -1464,7 +1464,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) + cd_table->l2.l1tab = dma_alloc_coherent(smmu->dev, l1size, + &cd_table->cdtab_dma, + GFP_KERNEL); +- if (!cd_table->l2.l2ptrs) { ++ if (!cd_table->l2.l1tab) { + ret = -ENOMEM; + goto err_free_l2ptrs; + } +-- +2.51.0 + diff --git a/queue-6.17/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch b/queue-6.17/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch new file mode 100644 index 0000000000..fb8a9c1605 --- /dev/null +++ b/queue-6.17/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch @@ -0,0 +1,39 @@ +From d877a40830fcb142216e198878056a266c6f8a7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:16:13 +0800 +Subject: iommu/vt-d: Fix unused invalidation hint in qi_desc_iotlb + +From: Aashish Sharma + +[ Upstream commit 6b38a108eeb3936b21643191db535a35dd7c890b ] + +Invalidation hint (ih) in the function 'qi_desc_iotlb' is initialized +to zero and never used. It is embedded in the 0th bit of the 'addr' +parameter. Get the correct 'ih' value from there. + +Fixes: f701c9f36bcb ("iommu/vt-d: Factor out invalidation descriptor composition") +Signed-off-by: Aashish Sharma +Link: https://lore.kernel.org/r/20251009010903.1323979-1-aashish@aashishsharma.net +Signed-off-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/intel/iommu.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h +index 21b2c3f85ddc5..96823fab06a71 100644 +--- a/drivers/iommu/intel/iommu.h ++++ b/drivers/iommu/intel/iommu.h +@@ -1100,7 +1100,7 @@ static inline void qi_desc_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, + struct qi_desc *desc) + { + u8 dw = 0, dr = 0; +- int ih = 0; ++ int ih = addr & 1; + + if (cap_write_drain(iommu->cap)) + dw = 1; +-- +2.51.0 + diff --git a/queue-6.17/ipv6-clear-ra-flags-when-adding-a-static-route.patch b/queue-6.17/ipv6-clear-ra-flags-when-adding-a-static-route.patch new file mode 100644 index 0000000000..29e591b8bd --- /dev/null +++ b/queue-6.17/ipv6-clear-ra-flags-when-adding-a-static-route.patch @@ -0,0 +1,54 @@ +From 54e73371c95c0e27a1d00e9fbe3dc67fa2c11741 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:59:38 +0100 +Subject: ipv6: clear RA flags when adding a static route + +From: Fernando Fernandez Mancera + +[ Upstream commit f72514b3c5698e4b900b25345e09f9ed33123de6 ] + +When an IPv6 Router Advertisement (RA) is received for a prefix, the +kernel creates the corresponding on-link route with flags RTF_ADDRCONF +and RTF_PREFIX_RT configured and RTF_EXPIRES if lifetime is set. + +If later a user configures a static IPv6 address on the same prefix the +kernel clears the RTF_EXPIRES flag but it doesn't clear the RTF_ADDRCONF +and RTF_PREFIX_RT. When the next RA for that prefix is received, the +kernel sees the route as RA-learned and wrongly configures back the +lifetime. This is problematic because if the route expires, the static +address won't have the corresponding on-link route. + +This fix clears the RTF_ADDRCONF and RTF_PREFIX_RT flags preventing that +the lifetime is configured when the next RA arrives. If the static +address is deleted, the route becomes RA-learned again. + +Fixes: 14ef37b6d00e ("ipv6: fix route lookup in addrconf_prefix_rcv()") +Reported-by: Garri Djavadyan +Closes: https://lore.kernel.org/netdev/ba807d39aca5b4dcf395cc11dca61a130a52cfd3.camel@gmail.com/ +Signed-off-by: Fernando Fernandez Mancera +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20251115095939.6967-1-fmancera@suse.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 02c16909f6182..2111af022d946 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1138,6 +1138,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_set_expires(iter, rt->expires); + fib6_add_gc_list(iter); + } ++ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { ++ iter->fib6_flags &= ~RTF_ADDRCONF; ++ iter->fib6_flags &= ~RTF_PREFIX_RT; ++ } + + if (rt->fib6_pmtu) + fib6_metric_set(iter, RTAX_MTU, +-- +2.51.0 + diff --git a/queue-6.17/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch b/queue-6.17/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch new file mode 100644 index 0000000000..6583f71627 --- /dev/null +++ b/queue-6.17/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch @@ -0,0 +1,40 @@ +From 8133833d700356c43d110fd9d31f7693366c2976 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:01 +0200 +Subject: irqchip/bcm2712-mip: Fix OF node reference imbalance + +From: Johan Hovold + +[ Upstream commit 0435bcc4e5858c632c1b6d5afa637580d9779890 ] + +The init callback must not decrement the reference count of the provided +irqchip OF node. + +This should not cause any trouble currently, but if the driver ever +starts probe deferring it could lead to warnings about reference +underflow and saturation. + +Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm2712-mip.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c +index 9bd7bc0bf6d59..256c2d59f717d 100644 +--- a/drivers/irqchip/irq-bcm2712-mip.c ++++ b/drivers/irqchip/irq-bcm2712-mip.c +@@ -239,7 +239,6 @@ static int __init mip_of_msi_init(struct device_node *node, struct device_node * + int ret; + + pdev = of_find_device_by_node(node); +- of_node_put(node); + if (!pdev) + return -EPROBE_DEFER; + +-- +2.51.0 + diff --git a/queue-6.17/irqchip-bcm2712-mip-fix-section-mismatch.patch b/queue-6.17/irqchip-bcm2712-mip-fix-section-mismatch.patch new file mode 100644 index 0000000000..bf285563b6 --- /dev/null +++ b/queue-6.17/irqchip-bcm2712-mip-fix-section-mismatch.patch @@ -0,0 +1,37 @@ +From 6c3a9927b3f80c98c110abea3ce06f2478df25ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:02 +0200 +Subject: irqchip/bcm2712-mip: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit a8452d1d59d46066051e676d5daa472cd08cb304 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm2712-mip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c +index 256c2d59f717d..8466646e5a2da 100644 +--- a/drivers/irqchip/irq-bcm2712-mip.c ++++ b/drivers/irqchip/irq-bcm2712-mip.c +@@ -232,7 +232,7 @@ static int mip_parse_dt(struct mip_priv *mip, struct device_node *np) + return ret; + } + +-static int __init mip_of_msi_init(struct device_node *node, struct device_node *parent) ++static int mip_of_msi_init(struct device_node *node, struct device_node *parent) + { + struct platform_device *pdev; + struct mip_priv *mip; +-- +2.51.0 + diff --git a/queue-6.17/irqchip-imx-mu-msi-fix-section-mismatch.patch b/queue-6.17/irqchip-imx-mu-msi-fix-section-mismatch.patch new file mode 100644 index 0000000000..cef3d31a8c --- /dev/null +++ b/queue-6.17/irqchip-imx-mu-msi-fix-section-mismatch.patch @@ -0,0 +1,63 @@ +From 0081331ffcf787350fe1c6641c2f5963fb907aab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:06 +0200 +Subject: irqchip/imx-mu-msi: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 64acfd8e680ff8992c101fe19aadb112ce551072 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index d2a4e8a61a42b..41df168aa7da2 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -296,9 +296,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int __init imx_mu_of_init(struct device_node *dn, +- struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { + struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; +@@ -416,20 +415,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + } + +-static int __init imx_mu_imx6sx_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + } + +-static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + } +-- +2.51.0 + diff --git a/queue-6.17/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch b/queue-6.17/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch new file mode 100644 index 0000000000..b716964aa3 --- /dev/null +++ b/queue-6.17/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch @@ -0,0 +1,50 @@ +From 5add5205325b3edbb823d63b6cb85424a40e6d63 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:03 +0200 +Subject: irqchip/irq-bcm7038-l1: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index 04fac0cc857fd..eda33bd5d080c 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -219,9 +219,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, + } + #endif + +-static int __init bcm7038_l1_init_one(struct device_node *dn, +- unsigned int idx, +- struct bcm7038_l1_chip *intc) ++static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, ++ struct bcm7038_l1_chip *intc) + { + struct resource res; + resource_size_t sz; +@@ -395,8 +394,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int __init bcm7038_l1_of_init(struct device_node *dn, +- struct device_node *parent) ++static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) + { + struct bcm7038_l1_chip *intc; + int idx, ret; +-- +2.51.0 + diff --git a/queue-6.17/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch b/queue-6.17/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..980248a00e --- /dev/null +++ b/queue-6.17/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch @@ -0,0 +1,79 @@ +From 1de2a2c619c55ef543afbc07090c978655a3a253 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:04 +0200 +Subject: irqchip/irq-bcm7120-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bfc0c5beab1fde843677923cf008f41d583c980a ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index ff22c31044018..b6c85560c42ea 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -143,8 +143,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + int ret; + +@@ -177,8 +176,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + unsigned int gc_idx; + +@@ -208,10 +206,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_probe(struct device_node *dn, +- struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, +- struct bcm7120_l2_intc_data *), ++ struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; +@@ -339,15 +336,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, + return ret; + } + +-static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); +-- +2.51.0 + diff --git a/queue-6.17/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch b/queue-6.17/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..908f3971ec --- /dev/null +++ b/queue-6.17/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch @@ -0,0 +1,58 @@ +From 2b5ae6a74affa736fdd296dd75f8036c2d5a0b1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:05 +0200 +Subject: irqchip/irq-brcmstb-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bbe1775924478e95372c2f896064ab6446000713 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index 1bec5b2cd3f0e..53e67c6c01f7a 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -138,10 +138,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable); + } + +-static int __init brcmstb_l2_intc_of_init(struct device_node *np, +- struct device_node *parent, +- const struct brcmstb_intc_init_params +- *init_params) ++static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; +@@ -257,14 +255,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, + return ret; + } + +-static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + } + +-static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + } +-- +2.51.0 + diff --git a/queue-6.17/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-6.17/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..fd1eae810d --- /dev/null +++ b/queue-6.17/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From 4cee2cfb13b3d14abeb43d336f7b9ab8febb9344 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-6.17/irqchip-renesas-rzg2l-fix-section-mismatch.patch b/queue-6.17/irqchip-renesas-rzg2l-fix-section-mismatch.patch new file mode 100644 index 0000000000..d2185d4616 --- /dev/null +++ b/queue-6.17/irqchip-renesas-rzg2l-fix-section-mismatch.patch @@ -0,0 +1,45 @@ +From 0b938709d55e512b404db841f1f1f1319aef9260 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:07 +0200 +Subject: irqchip/renesas-rzg2l: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 5b338fbb2b5b21d61a9eaba14dcf43108de30258 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: d011c022efe27579 ("irqchip/renesas-rzg2l: Add support for RZ/Five SoC") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-renesas-rzg2l.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c +index 360d88687e4f5..32fec9aa37c49 100644 +--- a/drivers/irqchip/irq-renesas-rzg2l.c ++++ b/drivers/irqchip/irq-renesas-rzg2l.c +@@ -597,14 +597,12 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * + return 0; + } + +-static int __init rzg2l_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip); + } + +-static int __init rzfive_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzfive_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip); + } +-- +2.51.0 + diff --git a/queue-6.17/irqchip-starfive-jh8100-fix-section-mismatch.patch b/queue-6.17/irqchip-starfive-jh8100-fix-section-mismatch.patch new file mode 100644 index 0000000000..3d4721c059 --- /dev/null +++ b/queue-6.17/irqchip-starfive-jh8100-fix-section-mismatch.patch @@ -0,0 +1,38 @@ +From 9f86250a30a6f5076f117764b991535c8e107d03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:08 +0200 +Subject: irqchip/starfive-jh8100: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit f798bdb9aa81c425184f92e3d0b44d3b53d10da7 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: e4e535036173 ("irqchip: Add StarFive external interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Changhuang Liang +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-starfive-jh8100-intc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c +index 2460798ec158b..117f2c651ebd0 100644 +--- a/drivers/irqchip/irq-starfive-jh8100-intc.c ++++ b/drivers/irqchip/irq-starfive-jh8100-intc.c +@@ -114,8 +114,7 @@ static void starfive_intc_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static int __init starfive_intc_init(struct device_node *intc, +- struct device_node *parent) ++static int starfive_intc_init(struct device_node *intc, struct device_node *parent) + { + struct starfive_irq_chip *irqc; + struct reset_control *rst; +-- +2.51.0 + diff --git a/queue-6.17/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch b/queue-6.17/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch new file mode 100644 index 0000000000..cdcc8e5f32 --- /dev/null +++ b/queue-6.17/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch @@ -0,0 +1,51 @@ +From 0d92a00174ada3a0fd92abde81c158e28b7355e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 08:13:32 -0700 +Subject: kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node + +From: Will Rosenberg + +[ Upstream commit 382b1e8f30f779af8d6d33268e53df7de579ef3c ] + +There exists a memory leak of kernfs_iattrs contained as an element +of kernfs_node allocated in __kernfs_new_node(). __kernfs_setattr() +allocates kernfs_iattrs as a sub-object, and the LSM security check +incorrectly errors out and does not free the kernfs_iattrs sub-object. + +Make an additional error out case that properly frees kernfs_iattrs if +security_kernfs_init_security() fails. + +Fixes: e19dfdc83b60 ("kernfs: initialize security of newly created nodes") +Co-developed-by: Oliver Rosenberg +Signed-off-by: Oliver Rosenberg +Signed-off-by: Will Rosenberg +Link: https://patch.msgid.link/20251125151332.2010687-1-whrosenb@asu.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/dir.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index a670ba3e565e0..5c0efd6b239f6 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -675,11 +675,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + if (parent) { + ret = security_kernfs_init_security(parent, kn); + if (ret) +- goto err_out3; ++ goto err_out4; + } + + return kn; + ++ err_out4: ++ simple_xattrs_free(&kn->iattr->xattrs, NULL); ++ kmem_cache_free(kernfs_iattrs_cache, kn->iattr); + err_out3: + spin_lock(&root->kernfs_idr_lock); + idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); +-- +2.51.0 + diff --git a/queue-6.17/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-6.17/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..7d3b90b2bb --- /dev/null +++ b/queue-6.17/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From 6fb61781ce271fc2b7b7b4f198fdb9718abc955a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index e95287416ef87..99df46f2d9f52 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-6.17/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch b/queue-6.17/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch new file mode 100644 index 0000000000..c41edbabcb --- /dev/null +++ b/queue-6.17/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch @@ -0,0 +1,51 @@ +From 01714f4091826423f7d1a53ac1ed9b489a389946 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:06:43 +0800 +Subject: leds: rgb: leds-qcom-lpg: Don't enable TRILED when configuring PWM + +From: Fenglin Wu + +[ Upstream commit 072cd5f458d76b9e15d89ebdaea8b5cb1312eeef ] + +The PWM signal from the LPG channel can be routed to PMIC GPIOs with +proper GPIO configuration, and it is not necessary to enable the +TRILED channel in that case. This also applies to the LPG channels +that mapped to TRILED channels. Additionally, enabling the TRILED +channel unnecessarily would cause a voltage increase in its power +supply. Hence remove it. + +Fixes: 24e2d05d1b68 ("leds: Add driver for Qualcomm LPG") +Signed-off-by: Fenglin Wu +Reviewed-by: Bjorn Andersson +Link: https://patch.msgid.link/20251119-lpg_triled_fix-v3-2-84b6dbdc774a@oss.qualcomm.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/rgb/leds-qcom-lpg.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c +index 4f2a178e3d265..e197f548cddb0 100644 +--- a/drivers/leds/rgb/leds-qcom-lpg.c ++++ b/drivers/leds/rgb/leds-qcom-lpg.c +@@ -2,7 +2,7 @@ + /* + * Copyright (c) 2017-2022 Linaro Ltd + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. +- * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -1247,8 +1247,6 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + + lpg_apply(chan); + +- triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); +- + out_unlock: + mutex_unlock(&lpg->lock); + +-- +2.51.0 + diff --git a/queue-6.17/leds-upboard-fix-module-alias.patch b/queue-6.17/leds-upboard-fix-module-alias.patch new file mode 100644 index 0000000000..53505e0d11 --- /dev/null +++ b/queue-6.17/leds-upboard-fix-module-alias.patch @@ -0,0 +1,36 @@ +From 190db35ff89d990ed3e47307cd2bb4930d498c70 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 17:36:25 +0200 +Subject: leds: upboard: Fix module alias + +From: Thomas Richard + +[ Upstream commit c06a017439110debd335b6864bc2d69835624235 ] + +The module alias does not match the cell name defined in the MFD driver, +preventing automatic loading when the driver is built as a module. So fix +the module alias to ensure proper module auto-loading. + +Fixes: 0ef2929a0181 ("leds: Add AAEON UP board LED driver") +Signed-off-by: Thomas Richard +Reviewed-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20251020-leds-upboard-fix-module-alias-v2-1-84ac5c3a1a81@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-upboard.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/leds/leds-upboard.c b/drivers/leds/leds-upboard.c +index b350eb294280f..12989b2f19530 100644 +--- a/drivers/leds/leds-upboard.c ++++ b/drivers/leds/leds-upboard.c +@@ -123,4 +123,4 @@ MODULE_AUTHOR("Gary Wang "); + MODULE_AUTHOR("Thomas Richard "); + MODULE_DESCRIPTION("UP Board LED driver"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:upboard-led"); ++MODULE_ALIAS("platform:upboard-leds"); +-- +2.51.0 + diff --git a/queue-6.17/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-6.17/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..1afc7115e9 --- /dev/null +++ b/queue-6.17/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From 1e72889228fb8dcd3b9c30b436d31166f5c01ef2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index eb0cb11d0d126..a356965c1d734 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1928,9 +1928,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1996,6 +1993,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-6.17/libbpf-fix-parsing-of-multi-split-btf.patch b/queue-6.17/libbpf-fix-parsing-of-multi-split-btf.patch new file mode 100644 index 0000000000..8ec34e33d2 --- /dev/null +++ b/queue-6.17/libbpf-fix-parsing-of-multi-split-btf.patch @@ -0,0 +1,51 @@ +From 8818b7e2599adc4a3cbf5ce3fbb0ba220ef48bcc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:33:08 +0000 +Subject: libbpf: Fix parsing of multi-split BTF + +From: Alan Maguire + +[ Upstream commit 4f596acc260e691a2e348f64230392f3472feea3 ] + +When creating multi-split BTF we correctly set the start string offset +to be the size of the base string section plus the base BTF start +string offset; the latter is needed for multi-split BTF since the +offset is non-zero there. + +Unfortunately the BTF parsing case needed that logic and it was +missed. + +Fixes: 4e29128a9ace ("libbpf/btf: Fix string handling to support multi-split BTF") +Signed-off-by: Alan Maguire +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20251104203309.318429-2-alan.maguire@oracle.com +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/btf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c +index 37682908cb0f3..ea9f3311bbac6 100644 +--- a/tools/lib/bpf/btf.c ++++ b/tools/lib/bpf/btf.c +@@ -1062,7 +1062,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf, b + if (base_btf) { + btf->base_btf = base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + if (is_mmap) { +@@ -5819,7 +5819,7 @@ void btf_set_base_btf(struct btf *btf, const struct btf *base_btf) + { + btf->base_btf = (struct btf *)base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + int btf__relocate(struct btf *btf, const struct btf *base_btf) +-- +2.51.0 + diff --git a/queue-6.17/locktorture-fix-memory-leak-in-param_set_cpumask.patch b/queue-6.17/locktorture-fix-memory-leak-in-param_set_cpumask.patch new file mode 100644 index 0000000000..e5d44ea613 --- /dev/null +++ b/queue-6.17/locktorture-fix-memory-leak-in-param_set_cpumask.patch @@ -0,0 +1,84 @@ +From 13cc23f9c62de3d8166f09efd7cc5af7ed2aa20f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 12:19:56 -0800 +Subject: locktorture: Fix memory leak in param_set_cpumask() + +From: Wang Liang + +[ Upstream commit e52b43883d084a9af263c573f2a1bd1ca5088389 ] + +With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via +alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when +setting the module parameter multiple times by sysfs interface or removing +module. + +Below kmemleak trace is seen for this issue: + +unreferenced object 0xffff888100aabff8 (size 8): + comm "bash", pid 323, jiffies 4295059233 + hex dump (first 8 bytes): + 07 00 00 00 00 00 00 00 ........ + backtrace (crc ac50919): + __kmalloc_node_noprof+0x2e5/0x420 + alloc_cpumask_var_node+0x1f/0x30 + param_set_cpumask+0x26/0xb0 [locktorture] + param_attr_store+0x93/0x100 + module_attr_store+0x1b/0x30 + kernfs_fop_write_iter+0x114/0x1b0 + vfs_write+0x300/0x410 + ksys_write+0x60/0xd0 + do_syscall_64+0xa4/0x260 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +This issue can be reproduced by: + insmod locktorture.ko bind_writers=1 + rmmod locktorture + +or: + insmod locktorture.ko bind_writers=1 + echo 2 > /sys/module/locktorture/parameters/bind_writers + +Considering that setting the module parameter 'bind_writers' or +'bind_readers' by sysfs interface has no real effect, set the parameter +permissions to 0444. To fix the memory leak when removing module, free +'bind_writers' and 'bind_readers' memory in lock_torture_cleanup(). + +Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters") +Suggested-by: Zhang Changzhong +Signed-off-by: Wang Liang +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/locking/locktorture.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c +index ce0362f0a8719..6567e5eeacc0e 100644 +--- a/kernel/locking/locktorture.c ++++ b/kernel/locking/locktorture.c +@@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = { + .get = param_get_cpumask, + }; + +-module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0644); +-module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0644); ++module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0444); ++module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0444); + + long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn); + +@@ -1211,6 +1211,10 @@ static void lock_torture_cleanup(void) + cxt.cur_ops->exit(); + cxt.init_called = false; + } ++ ++ free_cpumask_var(bind_readers); ++ free_cpumask_var(bind_writers); ++ + torture_cleanup_end(); + } + +-- +2.51.0 + diff --git a/queue-6.17/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-6.17/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..5e51014d5b --- /dev/null +++ b/queue-6.17/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From a7bd71b603ee749ff809d3c719b7fef4b900ab86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index 369d72f59b3c1..06fd910b3fd1a 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -187,13 +187,14 @@ static int mac_hid_toggle_emumouse(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-6.17/md-avoid-repeated-calls-to-del_gendisk.patch b/queue-6.17/md-avoid-repeated-calls-to-del_gendisk.patch new file mode 100644 index 0000000000..78eadf7634 --- /dev/null +++ b/queue-6.17/md-avoid-repeated-calls-to-del_gendisk.patch @@ -0,0 +1,76 @@ +From 7931ff139356d7a6f776323d1e1d25049da90878 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 14:34:19 +0800 +Subject: md: avoid repeated calls to del_gendisk + +From: Xiao Ni + +[ Upstream commit 90e3bb44c0a86e245d8e5c6520206fa113acb1ee ] + +There is a uaf problem which is found by case 23rdev-lifetime: + +Oops: general protection fault, probably for non-canonical address 0xdead000000000122 +RIP: 0010:bdi_unregister+0x4b/0x170 +Call Trace: + + __del_gendisk+0x356/0x3e0 + mddev_unlock+0x351/0x360 + rdev_attr_store+0x217/0x280 + kernfs_fop_write_iter+0x14a/0x210 + vfs_write+0x29e/0x550 + ksys_write+0x74/0xf0 + do_syscall_64+0xbb/0x380 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7ff5250a177e + +The sequence is: +1. rdev remove path gets reconfig_mutex +2. rdev remove path release reconfig_mutex in mddev_unlock +3. md stop calls do_md_stop and sets MD_DELETED +4. rdev remove path calls del_gendisk because MD_DELETED is set +5. md stop path release reconfig_mutex and calls del_gendisk again + +So there is a race condition we should resolve. This patch adds a +flag MD_DO_DELETE to avoid the race condition. + +Link: https://lore.kernel.org/linux-raid/20251029063419.21700-1-xni@redhat.com +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Signed-off-by: Xiao Ni +Suggested-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 3 ++- + drivers/md/md.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 436aab6c5d3de..209ca3eade260 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -887,7 +887,8 @@ void mddev_unlock(struct mddev *mddev) + * do_md_stop. dm raid only uses md_stop to stop. So dm raid + * doesn't need to check MD_DELETED when getting reconfig lock + */ +- if (test_bit(MD_DELETED, &mddev->flags)) { ++ if (test_bit(MD_DELETED, &mddev->flags) && ++ !test_and_set_bit(MD_DO_DELETE, &mddev->flags)) { + kobject_del(&mddev->kobj); + del_gendisk(mddev->gendisk); + } +diff --git a/drivers/md/md.h b/drivers/md/md.h +index c989cc9f6216b..0a1a227f106b0 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -353,6 +353,7 @@ enum mddev_flags { + MD_HAS_MULTIPLE_PPLS, + MD_NOT_READY, + MD_BROKEN, ++ MD_DO_DELETE, + MD_DELETED, + }; + +-- +2.51.0 + diff --git a/queue-6.17/md-delete-md_redundancy_group-when-array-is-becoming.patch b/queue-6.17/md-delete-md_redundancy_group-when-array-is-becoming.patch new file mode 100644 index 0000000000..17fdb1d029 --- /dev/null +++ b/queue-6.17/md-delete-md_redundancy_group-when-array-is-becoming.patch @@ -0,0 +1,69 @@ +From d072008a44b0729a446506063f0d3643cc3097ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 20:57:53 +0800 +Subject: md: delete md_redundancy_group when array is becoming inactive + +From: Li Nan + +[ Upstream commit 0ce112d9171ad766d4c6716951e73f91a0bfc184 ] + +'md_redundancy_group' are created in md_run() and deleted in del_gendisk(), +but these are not paired. Writing inactive/active to sysfs array_state can +trigger md_run() multiple times without del_gendisk(), leading to +duplicate creation as below: + + sysfs: cannot create duplicate filename '/devices/virtual/block/md0/md/sync_action' + Call Trace: + dump_stack_lvl+0x9f/0x120 + dump_stack+0x14/0x20 + sysfs_warn_dup+0x96/0xc0 + sysfs_add_file_mode_ns+0x19c/0x1b0 + internal_create_group+0x213/0x830 + sysfs_create_group+0x17/0x20 + md_run+0x856/0xe60 + ? __x64_sys_openat+0x23/0x30 + do_md_run+0x26/0x1d0 + array_state_store+0x559/0x760 + md_attr_store+0xc9/0x1e0 + sysfs_kf_write+0x6f/0xa0 + kernfs_fop_write_iter+0x141/0x2a0 + vfs_write+0x1fc/0x5a0 + ksys_write+0x79/0x180 + __x64_sys_write+0x1d/0x30 + x64_sys_call+0x2818/0x2880 + do_syscall_64+0xa9/0x580 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + md: cannot register extra attributes for md0 + +Creation of it depends on 'pers', its lifecycle cannot be aligned with +gendisk. So fix this issue by triggering 'md_redundancy_group' deletion +when the array is becoming inactive. + +Link: https://lore.kernel.org/linux-raid/20251103125757.1405796-2-linan666@huaweicloud.com +Fixes: 790abe4d77af ("md: remove/add redundancy group only in level change") +Signed-off-by: Li Nan +Reviewed-by: Xiao Ni +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 209ca3eade260..48345082d2eb3 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -6696,6 +6696,10 @@ static int do_md_stop(struct mddev *mddev, int mode) + if (!md_is_rdwr(mddev)) + set_disk_ro(disk, 0); + ++ if (mode == 2 && mddev->pers->sync_request && ++ mddev->to_remove == NULL) ++ mddev->to_remove = &md_redundancy_group; ++ + __md_stop_writes(mddev); + __md_stop(mddev); + +-- +2.51.0 + diff --git a/queue-6.17/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch b/queue-6.17/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch new file mode 100644 index 0000000000..1571a3ba0e --- /dev/null +++ b/queue-6.17/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch @@ -0,0 +1,60 @@ +From 797eb88ea55090e907d178113f68d141c7cdd82e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 09:24:24 +0800 +Subject: md: delete mddev kobj before deleting gendisk kobj + +From: Xiao Ni + +[ Upstream commit cc394b94dc40b661efc9895665abf03640ffff2d ] + +In sync del gendisk path, it deletes gendisk first and the directory +/sys/block/md is removed. Then it releases mddev kobj in a delayed work. +If we enable debug log in sysfs_remove_group, we can see the debug log +'sysfs group bitmap not found for kobject md'. It's the reason that the +parent kobj has been deleted, so it can't find parent directory. + +In creating path, it allocs gendisk first, then adds mddev kobj. So it +should delete mddev kobj before deleting gendisk. + +Before commit 9e59d609763f ("md: call del_gendisk in control path"), it +releases mddev kobj first. If the kobj hasn't been deleted, it does clean +job and deletes the kobj. Then it calls del_gendisk and releases gendisk +kobj. So it doesn't need to call kobject_del to delete mddev kobj. After +this patch, in sync del gendisk path, the sequence changes. So it needs +to call kobject_del to delete mddev kobj. + +After this patch, the sequence is: +1. kobject del mddev kobj +2. del_gendisk deletes gendisk kobj +3. mddev_delayed_delete releases mddev kobj +4. md_kobj_release releases gendisk kobj + +Link: https://lore.kernel.org/linux-raid/20250928012424.61370-1-xni@redhat.com +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Signed-off-by: Xiao Ni +Reviewed-by: Li Nan +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 4e033c26fdd46..07e48faa87e0b 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -887,8 +887,10 @@ void mddev_unlock(struct mddev *mddev) + * do_md_stop. dm raid only uses md_stop to stop. So dm raid + * doesn't need to check MD_DELETED when getting reconfig lock + */ +- if (test_bit(MD_DELETED, &mddev->flags)) ++ if (test_bit(MD_DELETED, &mddev->flags)) { ++ kobject_del(&mddev->kobj); + del_gendisk(mddev->gendisk); ++ } + } + } + EXPORT_SYMBOL_GPL(mddev_unlock); +-- +2.51.0 + diff --git a/queue-6.17/md-fix-rcu-protection-in-md_wakeup_thread.patch b/queue-6.17/md-fix-rcu-protection-in-md_wakeup_thread.patch new file mode 100644 index 0000000000..c61ba62982 --- /dev/null +++ b/queue-6.17/md-fix-rcu-protection-in-md_wakeup_thread.patch @@ -0,0 +1,114 @@ +From e077aacaff20250389eaf5e40e3b96e12e8b317f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:32:27 +0800 +Subject: md: fix rcu protection in md_wakeup_thread + +From: Yun Zhou + +[ Upstream commit 0dc76205549b4c25705e54345f211b9f66e018a0 ] + +We attempted to use RCU to protect the pointer 'thread', but directly +passed the value when calling md_wakeup_thread(). This means that the +RCU pointer has been acquired before rcu_read_lock(), which renders +rcu_read_lock() ineffective and could lead to a use-after-free. + +Link: https://lore.kernel.org/linux-raid/20251015083227.1079009-1-yun.zhou@windriver.com +Fixes: 446931543982 ("md: protect md_thread with rcu") +Signed-off-by: Yun Zhou +Reviewed-by: Li Nan +Reviewed-by: Yu Kuai +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 14 ++++++-------- + drivers/md/md.h | 8 +++++++- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 07e48faa87e0b..436aab6c5d3de 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -100,7 +100,7 @@ static int remove_and_add_spares(struct mddev *mddev, + struct md_rdev *this); + static void mddev_detach(struct mddev *mddev); + static void export_rdev(struct md_rdev *rdev, struct mddev *mddev); +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread); ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread); + + /* + * Default number of read corrections we'll attempt on an rdev +@@ -4984,7 +4984,7 @@ static void stop_sync_thread(struct mddev *mddev, bool locked) + * Thread might be blocked waiting for metadata update which will now + * never happen + */ +- md_wakeup_thread_directly(mddev->sync_thread); ++ md_wakeup_thread_directly(&mddev->sync_thread); + if (work_pending(&mddev->sync_work)) + flush_work(&mddev->sync_work); + +@@ -8196,22 +8196,21 @@ static int md_thread(void *arg) + return 0; + } + +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread) ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread) + { + struct md_thread *t; + + rcu_read_lock(); +- t = rcu_dereference(thread); ++ t = rcu_dereference(*thread); + if (t) + wake_up_process(t->tsk); + rcu_read_unlock(); + } + +-void md_wakeup_thread(struct md_thread __rcu *thread) ++void __md_wakeup_thread(struct md_thread __rcu *thread) + { + struct md_thread *t; + +- rcu_read_lock(); + t = rcu_dereference(thread); + if (t) { + pr_debug("md: waking up MD thread %s.\n", t->tsk->comm); +@@ -8219,9 +8218,8 @@ void md_wakeup_thread(struct md_thread __rcu *thread) + if (wq_has_sleeper(&t->wqueue)) + wake_up(&t->wqueue); + } +- rcu_read_unlock(); + } +-EXPORT_SYMBOL(md_wakeup_thread); ++EXPORT_SYMBOL(__md_wakeup_thread); + + struct md_thread *md_register_thread(void (*run) (struct md_thread *), + struct mddev *mddev, const char *name) +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 51af29a030793..c989cc9f6216b 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -878,6 +878,12 @@ struct md_io_clone { + + #define THREAD_WAKEUP 0 + ++#define md_wakeup_thread(thread) do { \ ++ rcu_read_lock(); \ ++ __md_wakeup_thread(thread); \ ++ rcu_read_unlock(); \ ++} while (0) ++ + static inline void safe_put_page(struct page *p) + { + if (p) put_page(p); +@@ -891,7 +897,7 @@ extern struct md_thread *md_register_thread( + struct mddev *mddev, + const char *name); + extern void md_unregister_thread(struct mddev *mddev, struct md_thread __rcu **threadp); +-extern void md_wakeup_thread(struct md_thread __rcu *thread); ++extern void __md_wakeup_thread(struct md_thread __rcu *thread); + extern void md_check_recovery(struct mddev *mddev); + extern void md_reap_sync_thread(struct mddev *mddev); + extern enum sync_action md_sync_action(struct mddev *mddev); +-- +2.51.0 + diff --git a/queue-6.17/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch b/queue-6.17/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch new file mode 100644 index 0000000000..d67f562b5e --- /dev/null +++ b/queue-6.17/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch @@ -0,0 +1,99 @@ +From b5630eb0caf6df2743ebf1eac1eb36ff8643bd19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 16:55:57 +0800 +Subject: md/raid5: fix IO hang when array is broken with IO inflight + +From: Yu Kuai + +[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ] + +Following test can cause IO hang: + +mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none +sleep 5 +echo 1 > /sys/block/sda/device/delete +echo 1 > /sys/block/sdb/device/delete +echo 1 > /sys/block/sdc/device/delete +echo 1 > /sys/block/sdd/device/delete + +dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct + +Root cause: + +1) all disks removed, however all rdevs in the array is still in sync, +IO will be issued normally. + +2) IO failure from sda, and set badblocks failed, sda will be faulty +and MD_SB_CHANGING_PENDING will be set. + +3) error recovery try to recover this IO from other disks, IO will be +issued to sdb, sdc, and sdd. + +4) IO failure from sdb, and set badblocks failed again, now array is +broken and will become read-only. + +5) IO failure from sdc and sdd, however, stripe can't be handled anymore +because MD_SB_CHANGING_PENDING is set: + +handle_stripe + handle_stripe + if (test_bit MD_SB_CHANGING_PENDING) + set_bit STRIPE_HANDLE + goto finish + // skip handling failed stripe + +release_stripe + if (test_bit STRIPE_HANDLE) + list_add_tail conf->hand_list + +6) later raid5d can't handle failed stripe as well: + +raid5d + md_check_recovery + md_update_sb + if (!md_is_rdwr()) + // can't clear pending bit + return + if (test_bit MD_SB_CHANGING_PENDING) + break; + // can't handle failed stripe + +Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, +fix this problem by skip this checking for read-only array. + +Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com +Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") +Signed-off-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 771ac1cbab995..8f45de227f1c4 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -4938,7 +4938,8 @@ static void handle_stripe(struct stripe_head *sh) + goto finish; + + if (s.handle_bad_blocks || +- test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { ++ (md_is_rdwr(conf->mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { + set_bit(STRIPE_HANDLE, &sh->state); + goto finish; + } +@@ -6753,7 +6754,8 @@ static void raid5d(struct md_thread *thread) + int batch_size, released; + unsigned int offset; + +- if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ if (md_is_rdwr(mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + + released = release_stripe_list(conf, conf->temp_inactive_list); +-- +2.51.0 + diff --git a/queue-6.17/media-ov02c10-fix-default-vertical-flip.patch b/queue-6.17/media-ov02c10-fix-default-vertical-flip.patch new file mode 100644 index 0000000000..4a12280f35 --- /dev/null +++ b/queue-6.17/media-ov02c10-fix-default-vertical-flip.patch @@ -0,0 +1,42 @@ +From 709329c3dedb5796f9014f130f19120e6653e901 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Aug 2025 02:13:19 +0200 +Subject: media: ov02c10: Fix default vertical flip + +From: Sebastian Reichel + +[ Upstream commit d5ebe3f7d13d4cee3ff7e718de23564915aaf163 ] + +The driver right now defaults to setting the vertical flip bit. This +conflicts with proper handling of the rotation property defined in +ACPI or device tree, so drop the VFLIP bit. It should be handled via +V4L2_CID_VFLIP instead. + +Reported-by: Frederic Stuyk +Closes: https://lore.kernel.org/all/b6df9ae7-ea9f-4e5a-8065-5b130f534f37@runbox.com/ +Fixes: 44f89010dae0 ("media: i2c: Add Omnivision OV02C10 sensor driver") +Signed-off-by: Sebastian Reichel +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ov02c10.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c +index 089a4fd9627cf..3a02fce0a9bc0 100644 +--- a/drivers/media/i2c/ov02c10.c ++++ b/drivers/media/i2c/ov02c10.c +@@ -175,7 +175,7 @@ static const struct reg_sequence sensor_1928x1092_30fps_setting[] = { + {0x3816, 0x01}, + {0x3817, 0x01}, + +- {0x3820, 0xb0}, ++ {0x3820, 0xa0}, + {0x3821, 0x00}, + {0x3822, 0x80}, + {0x3823, 0x08}, +-- +2.51.0 + diff --git a/queue-6.17/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-6.17/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..7a74165083 --- /dev/null +++ b/queue-6.17/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From d33dd1bbbe8d7b3d40085cfb350fd928b9cca1f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index 1f727ef60d638..8c989b74f924e 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.17/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..b1bc05413f --- /dev/null +++ b/queue-6.17/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From a7ec5b78ac64f99fba73a9cfb978affa1df141b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index f467b00d23660..74cf208430440 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -285,6 +285,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.17/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..5e5edd8c97 --- /dev/null +++ b/queue-6.17/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From d790235617cf812deadd76e82cf6d9e8da322cbc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 0e463026c5a91..5d2e5459f7444 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -229,6 +229,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch b/queue-6.17/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch new file mode 100644 index 0000000000..7305e8a8f1 --- /dev/null +++ b/queue-6.17/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch @@ -0,0 +1,42 @@ +From f49b785f20ea81d3e5f009d2d19edbffbe9f4eae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 08:14:04 +0100 +Subject: misc: rp1: Fix an error handling path in rp1_probe() + +From: Christophe JAILLET + +[ Upstream commit 43cd4b634ef90c4e2ff75eaeb361786fa04c8874 ] + +When DT is used to get the reference of 'rp1_node', it should be released +when not needed anymore, otherwise it is leaking. + +In such a case, add the missing of_node_put() call at the end of the probe, +as already done in the error handling path. + +Fixes: 49d63971f963 ("misc: rp1: RaspberryPi RP1 misc driver") +Signed-off-by: Christophe JAILLET +Reviewed-by: Andrea della Porta +Link: https://patch.msgid.link/9bc1206de787fa86384f3e5ba0a8027947bc00ff.1762585959.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/rp1/rp1_pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c +index 803832006ec87..a342bcc6164bb 100644 +--- a/drivers/misc/rp1/rp1_pci.c ++++ b/drivers/misc/rp1/rp1_pci.c +@@ -289,6 +289,9 @@ static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id) + goto err_unload_overlay; + } + ++ if (skip_ovl) ++ of_node_put(rp1_node); ++ + return 0; + + err_unload_overlay: +-- +2.51.0 + diff --git a/queue-6.17/mshv-fix-create-memory-region-overlap-check.patch b/queue-6.17/mshv-fix-create-memory-region-overlap-check.patch new file mode 100644 index 0000000000..d664458063 --- /dev/null +++ b/queue-6.17/mshv-fix-create-memory-region-overlap-check.patch @@ -0,0 +1,86 @@ +From 2bb0ef60915dc77dd4104c07aecc61504c6b7f85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:13:30 -0800 +Subject: mshv: Fix create memory region overlap check + +From: Nuno Das Neves + +[ Upstream commit ba9eb9b86d232854e983203dc2fb1ba18e316681 ] + +The current check is incorrect; it only checks if the beginning or end +of a region is within an existing region. This doesn't account for +userspace specifying a region that begins before and ends after an +existing region. + +Change the logic to a range intersection check against gfns and uaddrs +for each region. + +Remove mshv_partition_region_by_uaddr() as it is no longer used. + +Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Reported-by: Michael Kelley +Closes: https://lore.kernel.org/linux-hyperv/SN6PR02MB41575BE0406D3AB22E1D7DB5D4C2A@SN6PR02MB4157.namprd02.prod.outlook.com/ +Signed-off-by: Nuno Das Neves +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_root_main.c | 31 +++++++++++-------------------- + 1 file changed, 11 insertions(+), 20 deletions(-) + +diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c +index 618cac041441a..baa6a24066348 100644 +--- a/drivers/hv/mshv_root_main.c ++++ b/drivers/hv/mshv_root_main.c +@@ -1200,21 +1200,6 @@ mshv_partition_region_by_gfn(struct mshv_partition *partition, u64 gfn) + return NULL; + } + +-static struct mshv_mem_region * +-mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr) +-{ +- struct mshv_mem_region *region; +- +- hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { +- if (uaddr >= region->start_uaddr && +- uaddr < region->start_uaddr + +- (region->nr_pages << HV_HYP_PAGE_SHIFT)) +- return region; +- } +- +- return NULL; +-} +- + /* + * NB: caller checks and makes sure mem->size is page aligned + * Returns: 0 with regionpp updated on success, or -errno +@@ -1224,15 +1209,21 @@ static int mshv_partition_create_region(struct mshv_partition *partition, + struct mshv_mem_region **regionpp, + bool is_mmio) + { +- struct mshv_mem_region *region; ++ struct mshv_mem_region *region, *rg; + u64 nr_pages = HVPFN_DOWN(mem->size); + + /* Reject overlapping regions */ +- if (mshv_partition_region_by_gfn(partition, mem->guest_pfn) || +- mshv_partition_region_by_gfn(partition, mem->guest_pfn + nr_pages - 1) || +- mshv_partition_region_by_uaddr(partition, mem->userspace_addr) || +- mshv_partition_region_by_uaddr(partition, mem->userspace_addr + mem->size - 1)) ++ hlist_for_each_entry(rg, &partition->pt_mem_regions, hnode) { ++ u64 rg_size = rg->nr_pages << HV_HYP_PAGE_SHIFT; ++ ++ if ((mem->guest_pfn + nr_pages <= rg->start_gfn || ++ rg->start_gfn + rg->nr_pages <= mem->guest_pfn) && ++ (mem->userspace_addr + mem->size <= rg->start_uaddr || ++ rg->start_uaddr + rg_size <= mem->userspace_addr)) ++ continue; ++ + return -EEXIST; ++ } + + region = vzalloc(sizeof(*region) + sizeof(struct page *) * nr_pages); + if (!region) +-- +2.51.0 + diff --git a/queue-6.17/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch b/queue-6.17/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch new file mode 100644 index 0000000000..a3983705aa --- /dev/null +++ b/queue-6.17/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch @@ -0,0 +1,171 @@ +From 58e9d4ef342591fe42b8e068433bc4ac604eca2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 11:58:17 -0700 +Subject: mshv: Fix deposit memory in MSHV_ROOT_HVCALL + +From: Nuno Das Neves + +[ Upstream commit 4cc1aa469cd6b714adc958547a4866247bfd60a9 ] + +When the MSHV_ROOT_HVCALL ioctl is executing a hypercall, and gets +HV_STATUS_INSUFFICIENT_MEMORY, it deposits memory and then returns +-EAGAIN to userspace. The expectation is that the VMM will retry. + +However, some VMM code in the wild doesn't do this and simply fails. +Rather than force the VMM to retry, change the ioctl to deposit +memory on demand and immediately retry the hypercall as is done with +all the other hypercall helper functions. + +In addition to making the ioctl easier to use, removing the need for +multiple syscalls improves performance. + +There is a complication: unlike the other hypercall helper functions, +in MSHV_ROOT_HVCALL the input is opaque to the kernel. This is +problematic for rep hypercalls, because the next part of the input +list can't be copied on each loop after depositing pages (this was +the original reason for returning -EAGAIN in this case). + +Introduce hv_do_rep_hypercall_ex(), which adds a 'rep_start' +parameter. This solves the issue, allowing the deposit loop in +MSHV_ROOT_HVCALL to restart a rep hypercall after depositing pages +partway through. + +Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Signed-off-by: Nuno Das Neves +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_root_main.c | 58 ++++++++++++++++++---------------- + include/asm-generic/mshyperv.h | 17 ++++++++-- + 2 files changed, 44 insertions(+), 31 deletions(-) + +diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c +index cad09ff5f94dc..618cac041441a 100644 +--- a/drivers/hv/mshv_root_main.c ++++ b/drivers/hv/mshv_root_main.c +@@ -164,6 +164,7 @@ static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, + unsigned int pages_order; + void *input_pg = NULL; + void *output_pg = NULL; ++ u16 reps_completed; + + if (copy_from_user(&args, user_args, sizeof(args))) + return -EFAULT; +@@ -215,41 +216,42 @@ static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, + */ + *(u64 *)input_pg = partition->pt_id; + +- if (args.reps) +- status = hv_do_rep_hypercall(args.code, args.reps, 0, +- input_pg, output_pg); +- else +- status = hv_do_hypercall(args.code, input_pg, output_pg); +- +- if (hv_result(status) == HV_STATUS_CALL_PENDING) { +- if (is_async) { +- mshv_async_hvcall_handler(partition, &status); +- } else { /* Paranoia check. This shouldn't happen! */ +- ret = -EBADFD; +- goto free_pages_out; ++ reps_completed = 0; ++ do { ++ if (args.reps) { ++ status = hv_do_rep_hypercall_ex(args.code, args.reps, ++ 0, reps_completed, ++ input_pg, output_pg); ++ reps_completed = hv_repcomp(status); ++ } else { ++ status = hv_do_hypercall(args.code, input_pg, output_pg); + } +- } + +- if (hv_result(status) == HV_STATUS_INSUFFICIENT_MEMORY) { +- ret = hv_call_deposit_pages(NUMA_NO_NODE, partition->pt_id, 1); +- if (!ret) +- ret = -EAGAIN; +- } else if (!hv_result_success(status)) { +- ret = hv_result_to_errno(status); +- } ++ if (hv_result(status) == HV_STATUS_CALL_PENDING) { ++ if (is_async) { ++ mshv_async_hvcall_handler(partition, &status); ++ } else { /* Paranoia check. This shouldn't happen! */ ++ ret = -EBADFD; ++ goto free_pages_out; ++ } ++ } ++ ++ if (hv_result_success(status)) ++ break; ++ ++ if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) ++ ret = hv_result_to_errno(status); ++ else ++ ret = hv_call_deposit_pages(NUMA_NO_NODE, ++ partition->pt_id, 1); ++ } while (!ret); + +- /* +- * Always return the status and output data regardless of result. +- * The VMM may need it to determine how to proceed. E.g. the status may +- * contain the number of reps completed if a rep hypercall partially +- * succeeded. +- */ + args.status = hv_result(status); +- args.reps = args.reps ? hv_repcomp(status) : 0; ++ args.reps = reps_completed; + if (copy_to_user(user_args, &args, sizeof(args))) + ret = -EFAULT; + +- if (output_pg && ++ if (!ret && output_pg && + copy_to_user((void __user *)args.out_ptr, output_pg, args.out_sz)) + ret = -EFAULT; + +diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h +index a729b77983fab..18ee23174da03 100644 +--- a/include/asm-generic/mshyperv.h ++++ b/include/asm-generic/mshyperv.h +@@ -123,10 +123,12 @@ static inline unsigned int hv_repcomp(u64 status) + + /* + * Rep hypercalls. Callers of this functions are supposed to ensure that +- * rep_count and varhead_size comply with Hyper-V hypercall definition. ++ * rep_count, varhead_size, and rep_start comply with Hyper-V hypercall ++ * definition. + */ +-static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, +- void *input, void *output) ++static inline u64 hv_do_rep_hypercall_ex(u16 code, u16 rep_count, ++ u16 varhead_size, u16 rep_start, ++ void *input, void *output) + { + u64 control = code; + u64 status; +@@ -134,6 +136,7 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET; + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET; ++ control |= (u64)rep_start << HV_HYPERCALL_REP_START_OFFSET; + + do { + status = hv_do_hypercall(control, input, output); +@@ -151,6 +154,14 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + return status; + } + ++/* For the typical case where rep_start is 0 */ ++static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, ++ void *input, void *output) ++{ ++ return hv_do_rep_hypercall_ex(code, rep_count, varhead_size, 0, ++ input, output); ++} ++ + /* Generate the guest OS identifier as described in the Hyper-V TLFS */ + static inline u64 hv_generate_guest_id(u64 kernel_version) + { +-- +2.51.0 + diff --git a/queue-6.17/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-6.17/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..21b4cabc18 --- /dev/null +++ b/queue-6.17/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From 4428e8c7b3e720e7eec6155bdb120a9118db550b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 4064e193d4dec..08ee2e861c4e2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -874,8 +874,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-6.17/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-6.17/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..638ff405c5 --- /dev/null +++ b/queue-6.17/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From fb63e23edb0bb72614a531ac3d5fb0c9eb9dff13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index 14e36ae71958f..bd76479b90e4a 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-6.17/mtd-nand-relax-ecc-parameter-validation-check.patch b/queue-6.17/mtd-nand-relax-ecc-parameter-validation-check.patch new file mode 100644 index 0000000000..32cd262870 --- /dev/null +++ b/queue-6.17/mtd-nand-relax-ecc-parameter-validation-check.patch @@ -0,0 +1,53 @@ +From b31d5faaf07452dd4e8e864bb147a1978c00ed35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:42 +1300 +Subject: mtd: nand: relax ECC parameter validation check + +From: Aryan Srivastava + +[ Upstream commit 050553c683f21eebd7d1020df9b2ec852e2a9e4e ] + +Due to the custom handling and layouts of certain nand controllers this +validity check will always fail for certain layouts. The check +inherently depends on even chunk sizing and this is not always the +case. + +Modify the check to only print a warning, instead of failing to +init the attached NAND. This allows various 8 bit and 12 ECC strength +layouts to be used. + +Fixes: 68c18dae6888 ("mtd: rawnand: marvell: add missing layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/nand_base.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index 13e4060bd1b6a..a25145dbc16e1 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -6469,11 +6469,14 @@ static int nand_scan_tail(struct nand_chip *chip) + ecc->steps = mtd->writesize / ecc->size; + if (!base->ecc.ctx.nsteps) + base->ecc.ctx.nsteps = ecc->steps; +- if (ecc->steps * ecc->size != mtd->writesize) { +- WARN(1, "Invalid ECC parameters\n"); +- ret = -EINVAL; +- goto err_nand_manuf_cleanup; +- } ++ ++ /* ++ * Validity check: Warn if ECC parameters are not compatible with page size. ++ * Due to the custom handling of ECC blocks in certain controllers the check ++ * may result in an expected failure. ++ */ ++ if (ecc->steps * ecc->size != mtd->writesize) ++ pr_warn("ECC parameters may be invalid in reference to underlying NAND chip\n"); + + if (!ecc->total) { + ecc->total = ecc->steps * ecc->bytes; +-- +2.51.0 + diff --git a/queue-6.17/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch b/queue-6.17/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch new file mode 100644 index 0000000000..dd6931fb17 --- /dev/null +++ b/queue-6.17/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch @@ -0,0 +1,50 @@ +From 7e50836bfa8c9b6338876ed7236e34f5c413fc3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 17:47:47 +0800 +Subject: mtd: rawnand: lpc32xx_slc: fix GPIO descriptor leak on probe error + and remove + +From: Haotian Zhang + +[ Upstream commit cdf44f1add4ec9ee80569d5a43e6e9bba0d74c7a ] + +The driver calls gpiod_get_optional() in the probe function but +never calls gpiod_put() in the remove function or in the probe +error path. This leads to a GPIO descriptor resource leak. +The lpc32xx_mlc.c driver in the same directory handles this +correctly by calling gpiod_put() on both paths. + +Add gpiod_put() in the remove function and in the probe error path +to fix the resource leak. + +Fixes: 6b923db2867c ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") +Signed-off-by: Haotian Zhang +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/lpc32xx_slc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c +index b54d76547ffb2..fea3705a21386 100644 +--- a/drivers/mtd/nand/raw/lpc32xx_slc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c +@@ -937,6 +937,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) + dma_release_channel(host->dma_chan); + enable_wp: + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + + return res; + } +@@ -962,6 +963,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev) + writel(tmp, SLC_CTRL(host->io_base)); + + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + } + + static int lpc32xx_nand_resume(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.17/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch b/queue-6.17/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch new file mode 100644 index 0000000000..2dbd41ac6f --- /dev/null +++ b/queue-6.17/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch @@ -0,0 +1,45 @@ +From 71f6e2baf25949ec74fada09939716786a117327 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 00:35:51 +0800 +Subject: mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors + +From: Haotian Zhang + +[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ] + +devm_pm_runtime_enable() can fail due to memory allocation failures. +The current code ignores its return value and proceeds with +pm_runtime_resume_and_get(), which may operate on incorrectly +initialized runtime PM state. + +Check the return value of devm_pm_runtime_enable() and return the +error code if it fails. + +Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c +index ac8c1b80d7be9..201dd62b99905 100644 +--- a/drivers/mtd/nand/raw/renesas-nand-controller.c ++++ b/drivers/mtd/nand/raw/renesas-nand-controller.c +@@ -1336,7 +1336,10 @@ static int rnandc_probe(struct platform_device *pdev) + if (IS_ERR(rnandc->regs)) + return PTR_ERR(rnandc->regs); + +- devm_pm_runtime_enable(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +-- +2.51.0 + diff --git a/queue-6.17/nbd-defer-config-put-in-recv_work.patch b/queue-6.17/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..332167c97b --- /dev/null +++ b/queue-6.17/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From a37205f38d34647e304cbede9174bcb30d8e1f84 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index ad39ab95ea665..7a1e61cc47357 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -1024,9 +1024,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-6.17/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-6.17/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..f5549b670a --- /dev/null +++ b/queue-6.17/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From acb70e48e725c00313b682cdd108bd0f8b344f83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 7a1e61cc47357..9ba4b20b80ba2 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2241,12 +2241,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch b/queue-6.17/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch new file mode 100644 index 0000000000..d669ecdfcc --- /dev/null +++ b/queue-6.17/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch @@ -0,0 +1,235 @@ +From c45098d6693006939b38fdba29745587df409a4a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:48 +0100 +Subject: net: dsa: b53: add support for 5389/5397/5398 ARL entry format + +From: Jonas Gorski + +[ Upstream commit 300f78e8b6b7be17c2c78afeded75be68acb1aa7 ] + +BCM5389, BCM5397 and BCM5398 use a different ARL entry format with just +a 16 bit fwdentry register, as well as different search control and data +offsets. + +So add appropriate ops for them and switch those chips to use them. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-8-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 53 ++++++++++++++++++++++++++++++-- + drivers/net/dsa/b53/b53_priv.h | 26 ++++++++++++++++ + drivers/net/dsa/b53/b53_regs.h | 13 ++++++++ + 3 files changed, 89 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 50ed9b7157197..dedbd53412871 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1850,6 +1850,31 @@ static void b53_arl_write_entry_25(struct b53_device *dev, + mac_vid); + } + ++static void b53_arl_read_entry_89(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ u64 mac_vid; ++ u16 fwd_entry; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry); ++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry); ++} ++ ++static void b53_arl_write_entry_89(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_arl_from_entry_89(&mac_vid, &fwd_entry, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, ++ B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid); ++ b53_write16(dev, B53_ARLIO_PAGE, ++ B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); ++} ++ + static void b53_arl_read_entry_95(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +@@ -2017,6 +2042,8 @@ static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +@@ -2029,6 +2056,8 @@ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +@@ -2074,6 +2103,18 @@ static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, + b53_arl_to_entry_25(ent, mac_vid); + } + ++static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u16 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_89, ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_89, &fwd_entry); ++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry); ++} ++ + static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2664,6 +2705,12 @@ static const struct b53_arl_ops b53_arl_ops_65 = { + .arl_search_read = b53_arl_search_read_65, + }; + ++static const struct b53_arl_ops b53_arl_ops_89 = { ++ .arl_read_entry = b53_arl_read_entry_89, ++ .arl_write_entry = b53_arl_write_entry_89, ++ .arl_search_read = b53_arl_search_read_89, ++}; ++ + static const struct b53_arl_ops b53_arl_ops_95 = { + .arl_read_entry = b53_arl_read_entry_95, + .arl_write_entry = b53_arl_write_entry_95, +@@ -2728,7 +2775,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM5395_DEVICE_ID, +@@ -2756,7 +2803,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM5398_DEVICE_ID, +@@ -2770,7 +2817,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM53101_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index c6e2d5e41c758..127ce7f6b16ba 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -353,6 +353,18 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + ++static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent, ++ u64 mac_vid, u16 fwd_entry) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK_89; ++ ent->is_valid = !!(fwd_entry & ARLTBL_VALID_89); ++ ent->is_age = !!(fwd_entry & ARLTBL_AGE_89); ++ ent->is_static = !!(fwd_entry & ARLTBL_STATIC_89); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = mac_vid >> ARLTBL_VID_S; ++} ++ + static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, + const struct b53_arl_entry *ent) + { +@@ -383,6 +395,20 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + *mac_vid |= ARLTBL_AGE_25; + } + ++static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, ++ const struct b53_arl_entry *ent) ++{ ++ *mac_vid = ether_addr_to_u64(ent->mac); ++ *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S; ++ *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK_89; ++ if (ent->is_valid) ++ *fwd_entry |= ARLTBL_VALID_89; ++ if (ent->is_static) ++ *fwd_entry |= ARLTBL_STATIC_89; ++ if (ent->is_age) ++ *fwd_entry |= ARLTBL_AGE_89; ++} ++ + static inline void b53_arl_read_entry(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index 8ce1ce72e9385..d9026cf865549 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -342,12 +342,20 @@ + #define ARLTBL_STATIC BIT(15) + #define ARLTBL_VALID BIT(16) + ++/* BCM5389 ARL Table Data Entry N Register format (16 bit) */ ++#define ARLTBL_DATA_PORT_ID_MASK_89 GENMASK(8, 0) ++#define ARLTBL_TC_MASK_89 GENMASK(12, 10) ++#define ARLTBL_AGE_89 BIT(13) ++#define ARLTBL_STATIC_89 BIT(14) ++#define ARLTBL_VALID_89 BIT(15) ++ + /* Maximum number of bin entries in the ARL for all switches */ + #define B53_ARLTBL_MAX_BIN_ENTRIES 4 + + /* ARL Search Control Register (8 bit) */ + #define B53_ARL_SRCH_CTL 0x50 + #define B53_ARL_SRCH_CTL_25 0x20 ++#define B53_ARL_SRCH_CTL_89 0x30 + #define ARL_SRCH_VLID BIT(0) + #define ARL_SRCH_STDN BIT(7) + +@@ -355,10 +363,12 @@ + #define B53_ARL_SRCH_ADDR 0x51 + #define B53_ARL_SRCH_ADDR_25 0x22 + #define B53_ARL_SRCH_ADDR_65 0x24 ++#define B53_ARL_SRCH_ADDR_89 0x31 + #define ARL_ADDR_MASK GENMASK(14, 0) + + /* ARL Search MAC/VID Result (64 bit) */ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 ++#define B53_ARL_SRCH_RSLT_MACVID_89 0x33 + + /* Single register search result on 5325 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +@@ -368,6 +378,9 @@ + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 + ++/* BCM5389 ARL Search Data Result (16 bit) */ ++#define B53_ARL_SRCH_RSLT_89 0x3b ++ + #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) + #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) + +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch b/queue-6.17/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch new file mode 100644 index 0000000000..a0049fa254 --- /dev/null +++ b/queue-6.17/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch @@ -0,0 +1,192 @@ +From 9ff926b8c99e1d9a360f4fd51ca4d79b7b49c467 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:49 +0100 +Subject: net: dsa: b53: add support for bcm63xx ARL entry format + +From: Jonas Gorski + +[ Upstream commit 2b3013ac03028a2364d8779719bb6bfbc0212435 ] + +The ARL registers of BCM63XX embedded switches are somewhat unique. The +normal ARL table access registers have the same format as BCM5389, but +the ARL search registers differ: + +* SRCH_CTL is at the same offset of BCM5389, but 16 bits wide. It does + not have more fields, just needs to be accessed by a 16 bit read. +* SRCH_RSLT_MACVID and SRCH_RSLT are aligned to 32 bit, and have shifted + offsets. +* SRCH_RSLT has a different format than the normal ARL data entry + register. +* There is only one set of ENTRY_N registers, implying a 1 bin layout. + +So add appropriate ops for bcm63xx and let it use it. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-9-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 3b08863469aa ("net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 44 +++++++++++++++++++++++++++----- + drivers/net/dsa/b53/b53_priv.h | 15 +++++++++++ + drivers/net/dsa/b53/b53_regs.h | 9 +++++++ + 3 files changed, 61 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 68e9162087ab4..db1ed8c9c536e 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2042,12 +2042,20 @@ static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; +- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) || ++ is63xx(dev)) + offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +- b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++ if (is63xx(dev)) { ++ u16 val16; ++ ++ b53_read16(dev, B53_ARLIO_PAGE, offset, &val16); ++ *val = val16 & 0xff; ++ } else { ++ b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++ } + } + + static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) +@@ -2056,12 +2064,16 @@ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; +- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) || ++ is63xx(dev)) + offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +- b53_write8(dev, B53_ARLIO_PAGE, offset, val); ++ if (is63xx(dev)) ++ b53_write16(dev, B53_ARLIO_PAGE, offset, val); ++ else ++ b53_write8(dev, B53_ARLIO_PAGE, offset, val); + } + + static int b53_arl_search_wait(struct b53_device *dev) +@@ -2105,6 +2117,18 @@ static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, + b53_arl_to_entry_89(ent, mac_vid, fwd_entry); + } + ++static void b53_arl_search_read_63xx(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u16 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_63XX, ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_63XX, &fwd_entry); ++ b53_arl_search_to_entry_63xx(ent, mac_vid, fwd_entry); ++} ++ + static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2695,6 +2719,12 @@ static const struct b53_arl_ops b53_arl_ops_89 = { + .arl_search_read = b53_arl_search_read_89, + }; + ++static const struct b53_arl_ops b53_arl_ops_63xx = { ++ .arl_read_entry = b53_arl_read_entry_89, ++ .arl_write_entry = b53_arl_write_entry_89, ++ .arl_search_read = b53_arl_search_read_63xx, ++}; ++ + static const struct b53_arl_ops b53_arl_ops_95 = { + .arl_read_entry = b53_arl_read_entry_95, + .arl_write_entry = b53_arl_write_entry_95, +@@ -2864,14 +2894,14 @@ static const struct b53_chip_data b53_switch_chips[] = { + .dev_name = "BCM63xx", + .vlans = 4096, + .enabled_ports = 0, /* pdata must provide them */ +- .arl_bins = 4, +- .arl_buckets = 1024, ++ .arl_bins = 1, ++ .arl_buckets = 4096, + .imp_port = 8, + .vta_regs = B53_VTA_REGS_63XX, + .duplex_reg = B53_DUPLEX_STAT_63XX, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_63xx, + }, + { + .chip_id = BCM53010_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 80e7dd6169b47..ae2c615c088ed 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -414,6 +414,21 @@ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE_89; + } + ++static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent, ++ u64 mac_vid, u16 fwd_entry) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = mac_vid >> ARLTBL_VID_S; ++ ++ ent->port = fwd_entry & ARL_SRST_PORT_ID_MASK_63XX; ++ ent->port >>= 1; ++ ++ ent->is_age = !!(fwd_entry & ARL_SRST_AGE_63XX); ++ ent->is_static = !!(fwd_entry & ARL_SRST_STATIC_63XX); ++ ent->is_valid = 1; ++} ++ + static inline void b53_arl_read_entry(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index f2a3696d122fa..fcedd5fb00337 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -364,11 +364,13 @@ + #define B53_ARL_SRCH_ADDR_25 0x22 + #define B53_ARL_SRCH_ADDR_65 0x24 + #define B53_ARL_SRCH_ADDR_89 0x31 ++#define B53_ARL_SRCH_ADDR_63XX 0x32 + #define ARL_ADDR_MASK GENMASK(14, 0) + + /* ARL Search MAC/VID Result (64 bit) */ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 + #define B53_ARL_SRCH_RSLT_MACVID_89 0x33 ++#define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34 + + /* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +@@ -382,6 +384,13 @@ + #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) + #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) + ++/* 63XX ARL Search Data Result (16 bit) */ ++#define B53_ARL_SRCH_RSLT_63XX 0x3c ++#define ARL_SRST_PORT_ID_MASK_63XX GENMASK(9, 1) ++#define ARL_SRST_TC_MASK_63XX GENMASK(13, 11) ++#define ARL_SRST_AGE_63XX BIT(14) ++#define ARL_SRST_STATIC_63XX BIT(15) ++ + /************************************************************************* + * IEEE 802.1X Registers + *************************************************************************/ +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch b/queue-6.17/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch new file mode 100644 index 0000000000..49ff3813c7 --- /dev/null +++ b/queue-6.17/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch @@ -0,0 +1,95 @@ +From e9b4c9cadabf3a980638ccf6264bcf9d12a85663 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:42 +0100 +Subject: net: dsa: b53: b53_arl_read{,25}(): use the entry for comparision + +From: Jonas Gorski + +[ Upstream commit a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 ] + +Align the b53_arl_read{,25}() functions by consistently using the +parsed arl entry instead of parsing the raw registers again. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-2-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index a09ed32dccc07..4d8de90fb4ab8 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1830,7 +1830,7 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + return b53_arl_op_wait(dev); + } + +-static int b53_arl_read(struct b53_device *dev, u64 mac, ++static int b53_arl_read(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +@@ -1854,14 +1854,13 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, + B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); + b53_arl_to_entry(ent, mac_vid, fwd_entry); + +- if (!(fwd_entry & ARLTBL_VALID)) { ++ if (!ent->is_valid) { + set_bit(i, free_bins); + continue; + } +- if ((mac_vid & ARLTBL_MAC_MASK) != mac) ++ if (!ether_addr_equal(ent->mac, mac)) + continue; +- if (dev->vlan_enabled && +- ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid) ++ if (dev->vlan_enabled && ent->vid != vid) + continue; + *idx = i; + return 0; +@@ -1871,7 +1870,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, + return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; + } + +-static int b53_arl_read_25(struct b53_device *dev, u64 mac, ++static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +@@ -1893,14 +1892,13 @@ static int b53_arl_read_25(struct b53_device *dev, u64 mac, + + b53_arl_to_entry_25(ent, mac_vid); + +- if (!(mac_vid & ARLTBL_VALID_25)) { ++ if (!ent->is_valid) { + set_bit(i, free_bins); + continue; + } +- if ((mac_vid & ARLTBL_MAC_MASK) != mac) ++ if (!ether_addr_equal(ent->mac, mac)) + continue; +- if (dev->vlan_enabled && +- ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid) ++ if (dev->vlan_enabled && ent->vid != vid) + continue; + *idx = i; + return 0; +@@ -1937,9 +1935,9 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + return ret; + + if (is5325(dev) || is5365(dev)) +- ret = b53_arl_read_25(dev, mac, vid, &ent, &idx); ++ ret = b53_arl_read_25(dev, addr, vid, &ent, &idx); + else +- ret = b53_arl_read(dev, mac, vid, &ent, &idx); ++ ret = b53_arl_read(dev, addr, vid, &ent, &idx); + + /* If this is a read, just finish now */ + if (op) +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch b/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch new file mode 100644 index 0000000000..7fd8dd648c --- /dev/null +++ b/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch @@ -0,0 +1,134 @@ +From 6108d10a2356d833629b407488f81585d1d626ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:23 +0100 +Subject: net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks + +From: Jonas Gorski + +[ Upstream commit 3b08863469aa6028ac7c3120966f4e2f6051cf6b ] + +We currently use the mask 0xf for writing and reading b53_entry::port, +but this is only correct for unicast ARL entries. Multicast ARL entries +use a bitmask, and 0xf is not enough space for ports > 3, which includes +the CPU port. + +So extend the mask accordingly to also fit port 4 (bit 4) and MII (bit +5). According to the datasheet the multicast port mask is [60:48], +making it 12 bit wide, but bits 60-55 are reserved anyway, and collide +with the priority field at [60:59], so I am not sure if this is valid. +Therefore leave it at the actual used range, [53:48]. + +The ARL search result register differs a bit, and there the mask is only +[52:48], so only spanning the user ports. The MII port bit is +contained in the Search Result Extension register. So create a separate +search result parse function that properly handles this. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-6-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 4 +++- + drivers/net/dsa/b53/b53_priv.h | 25 +++++++++++++++++++++---- + drivers/net/dsa/b53/b53_regs.h | 8 +++++++- + 3 files changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index db1ed8c9c536e..5544e8e9c6446 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2099,10 +2099,12 @@ static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { + u64 mac_vid; ++ u8 ext; + ++ b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext); + b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, + &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); ++ b53_arl_search_to_entry_25(ent, mac_vid, ext); + } + + static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index ae2c615c088ed..f4afbfcc345e6 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -348,8 +348,8 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & +- ARLTBL_DATA_PORT_ID_MASK_25; ++ ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >> ++ ARLTBL_DATA_PORT_ID_S_25; + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + ent->port = B53_CPU_PORT_25; + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; +@@ -388,8 +388,8 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) + *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; + else +- *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << +- ARLTBL_DATA_PORT_ID_S_25; ++ *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) & ++ ARLTBL_DATA_PORT_ID_MASK_25; + *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << + ARLTBL_VID_S_65; + if (ent->is_valid) +@@ -414,6 +414,23 @@ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE_89; + } + ++static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent, ++ u64 mac_vid, u8 ext) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); ++ ent->is_age = !!(mac_vid & ARLTBL_AGE_25); ++ ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >> ++ ARL_SRCH_RSLT_PORT_ID_S_25; ++ if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII)) ++ ent->port |= BIT(B53_CPU_PORT_25); ++ else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ++ ent->port = B53_CPU_PORT_25; ++} ++ + static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent, + u64 mac_vid, u16 fwd_entry) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index fcedd5fb00337..e0379e70900b7 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -328,7 +328,7 @@ + #define ARLTBL_VID_MASK_25 0xff + #define ARLTBL_VID_MASK 0xfff + #define ARLTBL_DATA_PORT_ID_S_25 48 +-#define ARLTBL_DATA_PORT_ID_MASK_25 0xf ++#define ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48) + #define ARLTBL_VID_S_65 53 + #define ARLTBL_AGE_25 BIT_ULL(61) + #define ARLTBL_STATIC_25 BIT_ULL(62) +@@ -374,6 +374,12 @@ + + /* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 ++#define ARL_SRCH_RSLT_PORT_ID_S_25 48 ++#define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48) ++ ++/* BCM5325/5365 Search result extend register (8 bit) */ ++#define B53_ARL_SRCH_RSLT_EXT_25 0x2c ++#define ARL_SRCH_RSLT_EXT_MC_MII BIT(2) + + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch b/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch new file mode 100644 index 0000000000..507eed6298 --- /dev/null +++ b/queue-6.17/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch @@ -0,0 +1,154 @@ +From e3fc6b2bb96001ed0faf78f97ed8c2536cac4030 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:24 +0100 +Subject: net: dsa: b53: fix BCM5325/65 ARL entry VIDs + +From: Jonas Gorski + +[ Upstream commit d39514e6a2d14f57830d649e2bf03b49612c2f73 ] + +BCM5325/65's ARL entry registers do not contain the VID, only the search +result register does. ARL entries have a separate VID entry register for +the index into the VLAN table. + +So make ARL entry accessors use the VID entry registers instead, and +move the VLAN ID field definition to the search register definition. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-7-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 9 +++++++-- + drivers/net/dsa/b53/b53_priv.h | 12 ++++++------ + drivers/net/dsa/b53/b53_regs.h | 7 +++++-- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 5544e8e9c6446..62cafced758e7 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1833,19 +1833,24 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + static void b53_arl_read_entry_25(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { ++ u8 vid_entry; + u64 mac_vid; + ++ b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), ++ &vid_entry); + b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), + &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid, vid_entry); + } + + static void b53_arl_write_entry_25(struct b53_device *dev, + const struct b53_arl_entry *ent, u8 idx) + { ++ u8 vid_entry; + u64 mac_vid; + +- b53_arl_from_entry_25(&mac_vid, ent); ++ b53_arl_from_entry_25(&mac_vid, &vid_entry, ent); ++ b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry); + b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), + mac_vid); + } +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index f4afbfcc345e6..bd6849e5bb939 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -341,7 +341,7 @@ static inline void b53_arl_to_entry(struct b53_arl_entry *ent, + } + + static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, +- u64 mac_vid) ++ u64 mac_vid, u8 vid_entry) + { + memset(ent, 0, sizeof(*ent)); + ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); +@@ -352,7 +352,7 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ARLTBL_DATA_PORT_ID_S_25; + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + ent->port = B53_CPU_PORT_25; +- ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->vid = vid_entry; + } + + static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent, +@@ -381,7 +381,7 @@ static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE; + } + +-static inline void b53_arl_from_entry_25(u64 *mac_vid, ++static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry, + const struct b53_arl_entry *ent) + { + *mac_vid = ether_addr_to_u64(ent->mac); +@@ -390,14 +390,13 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + else + *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) & + ARLTBL_DATA_PORT_ID_MASK_25; +- *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << +- ARLTBL_VID_S_65; + if (ent->is_valid) + *mac_vid |= ARLTBL_VALID_25; + if (ent->is_static) + *mac_vid |= ARLTBL_STATIC_25; + if (ent->is_age) + *mac_vid |= ARLTBL_AGE_25; ++ *vid_entry = ent->vid; + } + + static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, +@@ -422,7 +421,8 @@ static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >> ++ ARL_SRCH_RSLT_VID_S_25; + ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >> + ARL_SRCH_RSLT_PORT_ID_S_25; + if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII)) +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index e0379e70900b7..b6fe7d207a2c1 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -325,11 +325,9 @@ + #define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10) + #define ARLTBL_MAC_MASK 0xffffffffffffULL + #define ARLTBL_VID_S 48 +-#define ARLTBL_VID_MASK_25 0xff + #define ARLTBL_VID_MASK 0xfff + #define ARLTBL_DATA_PORT_ID_S_25 48 + #define ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48) +-#define ARLTBL_VID_S_65 53 + #define ARLTBL_AGE_25 BIT_ULL(61) + #define ARLTBL_STATIC_25 BIT_ULL(62) + #define ARLTBL_VALID_25 BIT_ULL(63) +@@ -349,6 +347,9 @@ + #define ARLTBL_STATIC_89 BIT(14) + #define ARLTBL_VALID_89 BIT(15) + ++/* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */ ++#define B53_ARLTBL_VID_ENTRY_25(n) ((0x2 * (n)) + 0x30) ++ + /* Maximum number of bin entries in the ARL for all switches */ + #define B53_ARLTBL_MAX_BIN_ENTRIES 4 + +@@ -376,6 +377,8 @@ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 + #define ARL_SRCH_RSLT_PORT_ID_S_25 48 + #define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48) ++#define ARL_SRCH_RSLT_VID_S_25 53 ++#define ARL_SRCH_RSLT_VID_MASK_25 GENMASK_ULL(60, 53) + + /* BCM5325/5365 Search result extend register (8 bit) */ + #define B53_ARL_SRCH_RSLT_EXT_25 0x2c +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch b/queue-6.17/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch new file mode 100644 index 0000000000..164e5875b3 --- /dev/null +++ b/queue-6.17/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch @@ -0,0 +1,61 @@ +From c9155ba345baabff057a5989ff9552c2410d5c88 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:22 +0100 +Subject: net: dsa: b53: fix CPU port unicast ARL entries for BCM5325/65 + +From: Jonas Gorski + +[ Upstream commit 85132103f700b1340fc17df8a981509d17bf4872 ] + +On BCM5325 and BCM5365, unicast ARL entries use 8 as the value for the +CPU port, so we need to translate it to/from 5 as used for the CPU port +at most other places. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-5-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_priv.h | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 127ce7f6b16ba..80e7dd6169b47 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -344,12 +344,14 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + u64 mac_vid) + { + memset(ent, 0, sizeof(*ent)); +- ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & +- ARLTBL_DATA_PORT_ID_MASK_25; + ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); ++ ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & ++ ARLTBL_DATA_PORT_ID_MASK_25; ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ++ ent->port = B53_CPU_PORT_25; + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + +@@ -383,8 +385,11 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + const struct b53_arl_entry *ent) + { + *mac_vid = ether_addr_to_u64(ent->mac); +- *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << +- ARLTBL_DATA_PORT_ID_S_25; ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) ++ *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; ++ else ++ *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << ++ ARLTBL_DATA_PORT_ID_S_25; + *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << + ARLTBL_VID_S_65; + if (ent->is_valid) +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch b/queue-6.17/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch new file mode 100644 index 0000000000..6f13ef69ee --- /dev/null +++ b/queue-6.17/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch @@ -0,0 +1,45 @@ +From 59aecce7b995c83274a3e1174bdff548e00217ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:20 +0100 +Subject: net: dsa: b53: fix extracting VID from entry for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 9316012dd01952f75e37035360138ccc786ef727 ] + +BCM5325/65's Entry register uses the highest three bits for +VALID/STATIC/AGE, so shifting by 53 only will add these to +b53_arl_entry::vid. + +So make sure to mask the vid value as well, to not get invalid VIDs. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-3-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_priv.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 458775f951643..2f44b3b6a0d9f 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -338,7 +338,7 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->vid = mac_vid >> ARLTBL_VID_S_65; ++ ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + + static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch b/queue-6.17/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch new file mode 100644 index 0000000000..3afab8a193 --- /dev/null +++ b/queue-6.17/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch @@ -0,0 +1,48 @@ +From 0a8d15660a2b6591b10acdaea6bdac22efe8b5f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:19 +0100 +Subject: net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 6f268e275c74dae0536e0b61982a8db25bcf4f16 ] + +Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX +register is only 8 bit wide, not 16 bit, so use an appropriate accessor. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-2-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index eb767edc4c135..a09ed32dccc07 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1924,8 +1924,12 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + + /* Perform a read for the given MAC and VID */ + b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac); +- if (!is5325m(dev)) +- b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ if (!is5325m(dev)) { ++ if (is5325(dev) || is5365(dev)) ++ b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ else ++ b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ } + + /* Issue a read operation for this MAC */ + ret = b53_arl_rw_op(dev, 1); +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch b/queue-6.17/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch new file mode 100644 index 0000000000..b108f7222f --- /dev/null +++ b/queue-6.17/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch @@ -0,0 +1,361 @@ +From 7b14cbca7af1d38aa2ea630a514cdd6fd362d638 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:47 +0100 +Subject: net: dsa: b53: move ARL entry functions into ops struct + +From: Jonas Gorski + +[ Upstream commit a7e73339ad46ade76d29fb6cc7d7854222608c26 ] + +Now that the differences in ARL entry formats are neatly contained into +functions per chip family, wrap them into an ops struct and add wrapper +functions to access them. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-7-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 67 ++++++++++++++++++++++---------- + drivers/net/dsa/b53/b53_priv.h | 30 ++++++++++++++ + 2 files changed, 76 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 190eb11644917..50ed9b7157197 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1890,10 +1890,7 @@ static int b53_arl_read(struct b53_device *dev, const u8 *mac, + + /* Read the bins */ + for (i = 0; i < dev->num_arl_bins; i++) { +- if (is5325(dev) || is5365(dev)) +- b53_arl_read_entry_25(dev, ent, i); +- else +- b53_arl_read_entry_95(dev, ent, i); ++ b53_arl_read_entry(dev, ent, i); + + if (!ent->is_valid) { + set_bit(i, free_bins); +@@ -1979,10 +1976,7 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + ent.is_static = true; + ent.is_age = false; + memcpy(ent.mac, addr, ETH_ALEN); +- if (is5325(dev) || is5365(dev)) +- b53_arl_write_entry_25(dev, &ent, idx); +- else +- b53_arl_write_entry_95(dev, &ent, idx); ++ b53_arl_write_entry(dev, &ent, idx); + + return b53_arl_rw_op(dev, 0); + } +@@ -2093,17 +2087,6 @@ static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + +-static void b53_arl_search_rd(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) +-{ +- if (is5325(dev)) +- b53_arl_search_read_25(dev, idx, ent); +- else if (is5365(dev)) +- b53_arl_search_read_65(dev, idx, ent); +- else +- b53_arl_search_read_95(dev, idx, ent); +-} +- + static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, + dsa_fdb_dump_cb_t *cb, void *data) + { +@@ -2137,13 +2120,13 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, + if (ret) + break; + +- b53_arl_search_rd(priv, 0, &results[0]); ++ b53_arl_search_read(priv, 0, &results[0]); + ret = b53_fdb_copy(port, &results[0], cb, data); + if (ret) + break; + + if (results_per_hit == 2) { +- b53_arl_search_rd(priv, 1, &results[1]); ++ b53_arl_search_read(priv, 1, &results[1]); + ret = b53_fdb_copy(port, &results[1], cb, data); + if (ret) + break; +@@ -2669,6 +2652,24 @@ static const struct dsa_switch_ops b53_switch_ops = { + .port_change_mtu = b53_change_mtu, + }; + ++static const struct b53_arl_ops b53_arl_ops_25 = { ++ .arl_read_entry = b53_arl_read_entry_25, ++ .arl_write_entry = b53_arl_write_entry_25, ++ .arl_search_read = b53_arl_search_read_25, ++}; ++ ++static const struct b53_arl_ops b53_arl_ops_65 = { ++ .arl_read_entry = b53_arl_read_entry_25, ++ .arl_write_entry = b53_arl_write_entry_25, ++ .arl_search_read = b53_arl_search_read_65, ++}; ++ ++static const struct b53_arl_ops b53_arl_ops_95 = { ++ .arl_read_entry = b53_arl_read_entry_95, ++ .arl_write_entry = b53_arl_write_entry_95, ++ .arl_search_read = b53_arl_search_read_95, ++}; ++ + struct b53_chip_data { + u32 chip_id; + const char *dev_name; +@@ -2682,6 +2683,7 @@ struct b53_chip_data { + u8 duplex_reg; + u8 jumbo_pm_reg; + u8 jumbo_size_reg; ++ const struct b53_arl_ops *arl_ops; + }; + + #define B53_VTA_REGS \ +@@ -2701,6 +2703,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, ++ .arl_ops = &b53_arl_ops_25, + }, + { + .chip_id = BCM5365_DEVICE_ID, +@@ -2711,6 +2714,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, ++ .arl_ops = &b53_arl_ops_65, + }, + { + .chip_id = BCM5389_DEVICE_ID, +@@ -2724,6 +2728,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5395_DEVICE_ID, +@@ -2737,6 +2742,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5397_DEVICE_ID, +@@ -2750,6 +2756,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5398_DEVICE_ID, +@@ -2763,6 +2770,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53101_DEVICE_ID, +@@ -2776,6 +2784,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53115_DEVICE_ID, +@@ -2789,6 +2798,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53125_DEVICE_ID, +@@ -2802,6 +2812,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53128_DEVICE_ID, +@@ -2815,6 +2826,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM63XX_DEVICE_ID, +@@ -2828,6 +2840,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_63XX, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53010_DEVICE_ID, +@@ -2841,6 +2854,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53011_DEVICE_ID, +@@ -2854,6 +2868,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53012_DEVICE_ID, +@@ -2867,6 +2882,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53018_DEVICE_ID, +@@ -2880,6 +2896,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53019_DEVICE_ID, +@@ -2893,6 +2910,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM58XX_DEVICE_ID, +@@ -2906,6 +2924,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM583XX_DEVICE_ID, +@@ -2919,6 +2938,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + /* Starfighter 2 */ + { +@@ -2933,6 +2953,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM7445_DEVICE_ID, +@@ -2946,6 +2967,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM7278_DEVICE_ID, +@@ -2959,6 +2981,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53134_DEVICE_ID, +@@ -2973,6 +2996,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + }; + +@@ -3001,6 +3025,7 @@ static int b53_switch_init(struct b53_device *dev) + dev->num_vlans = chip->vlans; + dev->num_arl_bins = chip->arl_bins; + dev->num_arl_buckets = chip->arl_buckets; ++ dev->arl_ops = chip->arl_ops; + break; + } + } +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 2f44b3b6a0d9f..c6e2d5e41c758 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -58,6 +58,17 @@ struct b53_io_ops { + bool link_up); + }; + ++struct b53_arl_entry; ++ ++struct b53_arl_ops { ++ void (*arl_read_entry)(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx); ++ void (*arl_write_entry)(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx); ++ void (*arl_search_read)(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent); ++}; ++ + #define B53_INVALID_LANE 0xff + + enum { +@@ -127,6 +138,7 @@ struct b53_device { + struct mutex stats_mutex; + struct mutex arl_mutex; + const struct b53_io_ops *ops; ++ const struct b53_arl_ops *arl_ops; + + /* chip specific data */ + u32 chip_id; +@@ -371,6 +383,24 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + *mac_vid |= ARLTBL_AGE_25; + } + ++static inline void b53_arl_read_entry(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ dev->arl_ops->arl_read_entry(dev, ent, idx); ++} ++ ++static inline void b53_arl_write_entry(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ dev->arl_ops->arl_write_entry(dev, ent, idx); ++} ++ ++static inline void b53_arl_search_read(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ dev->arl_ops->arl_search_read(dev, idx, ent); ++} ++ + #ifdef CONFIG_BCM47XX + + #include +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch b/queue-6.17/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch new file mode 100644 index 0000000000..4c895c82a0 --- /dev/null +++ b/queue-6.17/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch @@ -0,0 +1,127 @@ +From d34054866046860b8e5ec95573bd1202a443b488 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:43 +0100 +Subject: net: dsa: b53: move reading ARL entries into their own function + +From: Jonas Gorski + +[ Upstream commit 4a291fe7226736a465ddb3fa93c21fcef7162ec7 ] + +Instead of duplicating the whole code iterating over all bins for +BCM5325, factor out reading and parsing the entry into its own +functions, and name it the modern one after the first chip with that ARL +format, (BCM53)95. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-3-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 69 +++++++++++--------------------- + 1 file changed, 23 insertions(+), 46 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 4d8de90fb4ab8..41dcd2d03230d 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1830,48 +1830,30 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + return b53_arl_op_wait(dev); + } + +-static int b53_arl_read(struct b53_device *dev, const u8 *mac, +- u16 vid, struct b53_arl_entry *ent, u8 *idx) ++static void b53_arl_read_entry_25(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) + { +- DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +- unsigned int i; +- int ret; +- +- ret = b53_arl_op_wait(dev); +- if (ret) +- return ret; +- +- bitmap_zero(free_bins, dev->num_arl_bins); +- +- /* Read the bins */ +- for (i = 0; i < dev->num_arl_bins; i++) { +- u64 mac_vid; +- u32 fwd_entry; ++ u64 mac_vid; + +- b53_read64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid); +- b53_read32(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); +- b53_arl_to_entry(ent, mac_vid, fwd_entry); ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} + +- if (!ent->is_valid) { +- set_bit(i, free_bins); +- continue; +- } +- if (!ether_addr_equal(ent->mac, mac)) +- continue; +- if (dev->vlan_enabled && ent->vid != vid) +- continue; +- *idx = i; +- return 0; +- } ++static void b53_arl_read_entry_95(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; + +- *idx = find_first_bit(free_bins, dev->num_arl_bins); +- return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry); ++ b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + +-static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, +- u16 vid, struct b53_arl_entry *ent, u8 *idx) ++static int b53_arl_read(struct b53_device *dev, const u8 *mac, ++ u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); + unsigned int i; +@@ -1885,12 +1867,10 @@ static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, + + /* Read the bins */ + for (i = 0; i < dev->num_arl_bins; i++) { +- u64 mac_vid; +- +- b53_read64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid); +- +- b53_arl_to_entry_25(ent, mac_vid); ++ if (is5325(dev) || is5365(dev)) ++ b53_arl_read_entry_25(dev, ent, i); ++ else ++ b53_arl_read_entry_95(dev, ent, i); + + if (!ent->is_valid) { + set_bit(i, free_bins); +@@ -1934,10 +1914,7 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + if (ret) + return ret; + +- if (is5325(dev) || is5365(dev)) +- ret = b53_arl_read_25(dev, addr, vid, &ent, &idx); +- else +- ret = b53_arl_read(dev, addr, vid, &ent, &idx); ++ ret = b53_arl_read(dev, addr, vid, &ent, &idx); + + /* If this is a read, just finish now */ + if (op) +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch b/queue-6.17/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch new file mode 100644 index 0000000000..947f0abdb5 --- /dev/null +++ b/queue-6.17/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch @@ -0,0 +1,103 @@ +From f2ff8ea1b1aa32712763c8be8de372281ecc376b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:44 +0100 +Subject: net: dsa: b53: move writing ARL entries into their own functions + +From: Jonas Gorski + +[ Upstream commit bf6e9d2ae1dbafee53ec4ccd126595172e1e5278 ] + +Move writing ARL entries into individual functions for each format. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-4-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 38 ++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 41dcd2d03230d..4c418e0531f73 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1840,6 +1840,16 @@ static void b53_arl_read_entry_25(struct b53_device *dev, + b53_arl_to_entry_25(ent, mac_vid); + } + ++static void b53_arl_write_entry_25(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u64 mac_vid; ++ ++ b53_arl_from_entry_25(&mac_vid, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ mac_vid); ++} ++ + static void b53_arl_read_entry_95(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +@@ -1852,6 +1862,19 @@ static void b53_arl_read_entry_95(struct b53_device *dev, + b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + ++static void b53_arl_write_entry_95(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_arl_from_entry(&mac_vid, &fwd_entry, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ mac_vid); ++ b53_write32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), ++ fwd_entry); ++} ++ + static int b53_arl_read(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { +@@ -1892,9 +1915,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + const unsigned char *addr, u16 vid, bool is_valid) + { + struct b53_arl_entry ent; +- u32 fwd_entry; +- u64 mac, mac_vid = 0; + u8 idx = 0; ++ u64 mac; + int ret; + + /* Convert the array into a 64-bit MAC */ +@@ -1931,7 +1953,6 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + /* We could not find a matching MAC, so reset to a new entry */ + dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n", + addr, vid, idx); +- fwd_entry = 0; + break; + default: + dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n", +@@ -1959,16 +1980,9 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + ent.is_age = false; + memcpy(ent.mac, addr, ETH_ALEN); + if (is5325(dev) || is5365(dev)) +- b53_arl_from_entry_25(&mac_vid, &ent); ++ b53_arl_write_entry_25(dev, &ent, idx); + else +- b53_arl_from_entry(&mac_vid, &fwd_entry, &ent); +- +- b53_write64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid); +- +- if (!is5325(dev) && !is5365(dev)) +- b53_write32(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); ++ b53_arl_write_entry_95(dev, &ent, idx); + + return b53_arl_rw_op(dev, 0); + } +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch b/queue-6.17/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch new file mode 100644 index 0000000000..c1bb5981d9 --- /dev/null +++ b/queue-6.17/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch @@ -0,0 +1,96 @@ +From 8c188f64affa4045d0ca3ad8c1c2b5209bc7e334 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:45 +0100 +Subject: net: dsa: b53: provide accessors for accessing ARL_SRCH_CTL + +From: Jonas Gorski + +[ Upstream commit 1716be6db04af53bac9b869f01156a460595cf41 ] + +In order to more easily support more formats, move accessing +ARL_SRCH_CTL into helper functions to contain the differences. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-5-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 37 +++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 4c418e0531f73..38e6fa05042ca 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2017,18 +2017,37 @@ int b53_fdb_del(struct dsa_switch *ds, int port, + } + EXPORT_SYMBOL(b53_fdb_del); + +-static int b53_arl_search_wait(struct b53_device *dev) ++static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + { +- unsigned int timeout = 1000; +- u8 reg, offset; ++ u8 offset; ++ ++ if (is5325(dev) || is5365(dev)) ++ offset = B53_ARL_SRCH_CTL_25; ++ else ++ offset = B53_ARL_SRCH_CTL; ++ ++ b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++} ++ ++static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) ++{ ++ u8 offset; + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; + else + offset = B53_ARL_SRCH_CTL; + ++ b53_write8(dev, B53_ARLIO_PAGE, offset, val); ++} ++ ++static int b53_arl_search_wait(struct b53_device *dev) ++{ ++ unsigned int timeout = 1000; ++ u8 reg; ++ + do { +- b53_read8(dev, B53_ARLIO_PAGE, offset, ®); ++ b53_read_arl_srch_ctl(dev, ®); + if (!(reg & ARL_SRCH_STDN)) + return -ENOENT; + +@@ -2083,23 +2102,15 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, + unsigned int count = 0, results_per_hit = 1; + struct b53_device *priv = ds->priv; + struct b53_arl_entry results[2]; +- u8 offset; + int ret; +- u8 reg; + + if (priv->num_arl_bins > 2) + results_per_hit = 2; + + mutex_lock(&priv->arl_mutex); + +- if (is5325(priv) || is5365(priv)) +- offset = B53_ARL_SRCH_CTL_25; +- else +- offset = B53_ARL_SRCH_CTL; +- + /* Start search operation */ +- reg = ARL_SRCH_STDN; +- b53_write8(priv, B53_ARLIO_PAGE, offset, reg); ++ b53_write_arl_srch_ctl(priv, ARL_SRCH_STDN); + + do { + ret = b53_arl_search_wait(priv); +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-split-reading-search-entry-into-their-ow.patch b/queue-6.17/net-dsa-b53-split-reading-search-entry-into-their-ow.patch new file mode 100644 index 0000000000..4bd7383613 --- /dev/null +++ b/queue-6.17/net-dsa-b53-split-reading-search-entry-into-their-ow.patch @@ -0,0 +1,95 @@ +From 07b7494f32b77345a67a2dada8275cb6d160baa5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:46 +0100 +Subject: net: dsa: b53: split reading search entry into their own functions + +From: Jonas Gorski + +[ Upstream commit e0c476f325a8c9b961a3d446c24d3c8ecae7d186 ] + +Split reading search entries into a function for each format. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-6-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 56 ++++++++++++++++++++++---------- + 1 file changed, 38 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 38e6fa05042ca..190eb11644917 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2060,28 +2060,48 @@ static int b53_arl_search_wait(struct b53_device *dev) + return -ETIMEDOUT; + } + +-static void b53_arl_search_rd(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) ++static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) + { + u64 mac_vid; + +- if (is5325(dev)) { +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +- } else if (is5365(dev)) { +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +- } else { +- u32 fwd_entry; ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} + +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx), +- &mac_vid); +- b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx), +- &fwd_entry); +- b53_arl_to_entry(ent, mac_vid, fwd_entry); +- } ++static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} ++ ++static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx), ++ &mac_vid); ++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx), ++ &fwd_entry); ++ b53_arl_to_entry(ent, mac_vid, fwd_entry); ++} ++ ++static void b53_arl_search_rd(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ if (is5325(dev)) ++ b53_arl_search_read_25(dev, idx, ent); ++ else if (is5365(dev)) ++ b53_arl_search_read_65(dev, idx, ent); ++ else ++ b53_arl_search_read_95(dev, idx, ent); + } + + static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch b/queue-6.17/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch new file mode 100644 index 0000000000..b46957377e --- /dev/null +++ b/queue-6.17/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch @@ -0,0 +1,90 @@ +From d10c1dae98e6ba9dd94cb3256da5f124f2420ed9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:21 +0100 +Subject: net: dsa: b53: use same ARL search result offset for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 8e46aacea4264bcb8d4265fb07577afff58ae78d ] + +BCM5365's search result is at the same offset as BCM5325's search +result, and they (mostly) share the same format, so switch BCM5365 to +BCM5325's arl ops. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-4-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 18 +----------------- + drivers/net/dsa/b53/b53_regs.h | 4 +--- + 2 files changed, 2 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index dedbd53412871..68e9162087ab4 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2093,16 +2093,6 @@ static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, + b53_arl_to_entry_25(ent, mac_vid); + } + +-static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) +-{ +- u64 mac_vid; +- +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +-} +- + static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2699,12 +2689,6 @@ static const struct b53_arl_ops b53_arl_ops_25 = { + .arl_search_read = b53_arl_search_read_25, + }; + +-static const struct b53_arl_ops b53_arl_ops_65 = { +- .arl_read_entry = b53_arl_read_entry_25, +- .arl_write_entry = b53_arl_write_entry_25, +- .arl_search_read = b53_arl_search_read_65, +-}; +- + static const struct b53_arl_ops b53_arl_ops_89 = { + .arl_read_entry = b53_arl_read_entry_89, + .arl_write_entry = b53_arl_write_entry_89, +@@ -2761,7 +2745,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, +- .arl_ops = &b53_arl_ops_65, ++ .arl_ops = &b53_arl_ops_25, + }, + { + .chip_id = BCM5389_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index d9026cf865549..f2a3696d122fa 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -370,10 +370,8 @@ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 + #define B53_ARL_SRCH_RSLT_MACVID_89 0x33 + +-/* Single register search result on 5325 */ ++/* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +-/* Single register search result on 5365 */ +-#define B53_ARL_SRCH_RSTL_0_MACVID_65 0x30 + + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 +-- +2.51.0 + diff --git a/queue-6.17/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch b/queue-6.17/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch new file mode 100644 index 0000000000..3722603cf8 --- /dev/null +++ b/queue-6.17/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch @@ -0,0 +1,83 @@ +From 9297578978a4085c011db99fa6e91cdb0f715d6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:46 +0200 +Subject: net: dsa: xrs700x: reject unsupported HSR configurations + +From: Vladimir Oltean + +[ Upstream commit 30296ac7642652428396222e720718f2661e9425 ] + +As discussed here: +https://lore.kernel.org/netdev/20240620090210.drop6jwh7e5qw556@skbuf/ + +the fact is that the xrs700x.c driver only supports offloading +HSR_PT_SLAVE_A and HSR_PT_SLAVE_B (which were the only port types at the +time the offload was written, _for this driver_). + +Up until now, the API did not explicitly tell offloading drivers what +port has what role. So xrs700x can get confused and think that it can +support a configuration which it actually can't. There was a table in +the attached link which gave an example: + +$ ip link add name hsr0 type hsr slave1 swp0 slave2 swp1 \ + interlink swp2 supervision 45 version 1 + + HSR_PT_SLAVE_A HSR_PT_SLAVE_B HSR_PT_INTERLINK + ---------------------------------------------------------------- + user + space 0 1 2 + requests + ---------------------------------------------------------------- + XRS700X + driver 1 2 - + understands + +The switch would act as if the ring ports were swp1 and swp2. + +Now that we have explicit hsr_get_port_type() API, let's use that to +work around the unintended semantical changes of the offloading API +brought by the introduction of interlink ports in HSR. + +Fixes: 5055cccfc2d1 ("net: hsr: Provide RedBox support (HSR-SAN)") +Cc: Lukasz Majewski +Signed-off-by: Vladimir Oltean +Reviewed-by: George McCollister +Link: https://patch.msgid.link/20251130131657.65080-5-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/xrs700x/xrs700x.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c +index 4dbcc49a9e526..0a05f4156ef4d 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x.c ++++ b/drivers/net/dsa/xrs700x/xrs700x.c +@@ -566,6 +566,7 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + struct xrs700x *priv = ds->priv; + struct net_device *user; + int ret, i, hsr_pair[2]; ++ enum hsr_port_type type; + enum hsr_version ver; + bool fwd = false; + +@@ -589,6 +590,16 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + return -EOPNOTSUPP; + } + ++ ret = hsr_get_port_type(hsr, dsa_to_port(ds, port)->user, &type); ++ if (ret) ++ return ret; ++ ++ if (type != HSR_PT_SLAVE_A && type != HSR_PT_SLAVE_B) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Only HSR slave ports can be offloaded"); ++ return -EOPNOTSUPP; ++ } ++ + dsa_hsr_foreach_port(dp, ds, hsr) { + if (dp->index != port) { + partner = dp; +-- +2.51.0 + diff --git a/queue-6.17/net-hsr-create-an-api-to-get-hsr-port-type.patch b/queue-6.17/net-hsr-create-an-api-to-get-hsr-port-type.patch new file mode 100644 index 0000000000..2e061932bc --- /dev/null +++ b/queue-6.17/net-hsr-create-an-api-to-get-hsr-port-type.patch @@ -0,0 +1,135 @@ +From 008171f865389732c9c66a97933a76850ed6793a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:44 +0200 +Subject: net: hsr: create an API to get hsr port type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiaoliang Yang + +[ Upstream commit a0244e76213980f3b9bb5d40b0b6705fcf24230d ] + +Since the introduction of HSR_PT_INTERLINK in commit 5055cccfc2d1 ("net: +hsr: Provide RedBox support (HSR-SAN)"), we see that different port +types require different settings for hardware offload, which was not the +case before when we only had HSR_PT_SLAVE_A and HSR_PT_SLAVE_B. But +there is currently no way to know which port is which type, so create +the hsr_get_port_type() API function and export it. + +When hsr_get_port_type() is called from the device driver, the port can +must be found in the HSR port list. An important use case is for this +function to work from offloading drivers' NETDEV_CHANGEUPPER handler, +which is triggered by hsr_portdev_setup() -> netdev_master_upper_dev_link(). +Therefore, we need to move the addition of the hsr_port to the HSR port +list prior to calling hsr_portdev_setup(). This makes the error +restoration path also more similar to hsr_del_port(), where +kfree_rcu(port) is already used. + +Cc: Sebastian Andrzej Siewior +Cc: Lukasz Majewski +Signed-off-by: Xiaoliang Yang +Signed-off-by: Vladimir Oltean +Reviewed-by: Łukasz Majewski +Link: https://patch.msgid.link/20251130131657.65080-3-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + include/linux/if_hsr.h | 9 +++++++++ + net/hsr/hsr_device.c | 20 ++++++++++++++++++++ + net/hsr/hsr_slave.c | 7 ++++--- + 3 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/include/linux/if_hsr.h b/include/linux/if_hsr.h +index d7941fd880329..f4cf2dd36d193 100644 +--- a/include/linux/if_hsr.h ++++ b/include/linux/if_hsr.h +@@ -43,6 +43,8 @@ extern bool is_hsr_master(struct net_device *dev); + extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver); + struct net_device *hsr_get_port_ndev(struct net_device *ndev, + enum hsr_port_type pt); ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type); + #else + static inline bool is_hsr_master(struct net_device *dev) + { +@@ -59,6 +61,13 @@ static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev, + { + return ERR_PTR(-EINVAL); + } ++ ++static inline int hsr_get_port_type(struct net_device *hsr_dev, ++ struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ return -EINVAL; ++} + #endif /* CONFIG_HSR */ + + #endif /*_LINUX_IF_HSR_H_*/ +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index 492cbc78ab75a..d1bfc49b5f017 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -690,6 +690,26 @@ struct net_device *hsr_get_port_ndev(struct net_device *ndev, + } + EXPORT_SYMBOL(hsr_get_port_ndev); + ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ struct hsr_priv *hsr = netdev_priv(hsr_dev); ++ struct hsr_port *port; ++ ++ rcu_read_lock(); ++ hsr_for_each_port(hsr, port) { ++ if (port->dev == dev) { ++ *type = port->type; ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return -EINVAL; ++} ++EXPORT_SYMBOL(hsr_get_port_type); ++ + /* Default multicast address for HSR Supervision frames */ + static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = { + 0x01, 0x15, 0x4e, 0x00, 0x01, 0x00 +diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c +index 102eccf5ead73..82c0bc69c9b34 100644 +--- a/net/hsr/hsr_slave.c ++++ b/net/hsr/hsr_slave.c +@@ -204,14 +204,14 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + port->type = type; + ether_addr_copy(port->original_macaddress, dev->dev_addr); + ++ list_add_tail_rcu(&port->port_list, &hsr->ports); ++ + if (type != HSR_PT_MASTER) { + res = hsr_portdev_setup(hsr, dev, port, extack); + if (res) + goto fail_dev_setup; + } + +- list_add_tail_rcu(&port->port_list, &hsr->ports); +- + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + netdev_update_features(master->dev); + dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); +@@ -219,7 +219,8 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + return 0; + + fail_dev_setup: +- kfree(port); ++ list_del_rcu(&port->port_list); ++ kfree_rcu(port, rcu); + return res; + } + +-- +2.51.0 + diff --git a/queue-6.17/net-netpoll-initialize-work-queue-before-error-check.patch b/queue-6.17/net-netpoll-initialize-work-queue-before-error-check.patch new file mode 100644 index 0000000000..882c252eb4 --- /dev/null +++ b/queue-6.17/net-netpoll-initialize-work-queue-before-error-check.patch @@ -0,0 +1,56 @@ +From 3ca955b345ee0d6881bc26288a4bf4f97acd3e8c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 07:30:15 -0800 +Subject: net: netpoll: initialize work queue before error checks + +From: Breno Leitao + +[ Upstream commit e5235eb6cfe02a51256013a78f7b28779a7740d5 ] + +Prevent a kernel warning when netconsole setup fails on devices with +IFF_DISABLE_NETPOLL flag. The warning (at kernel/workqueue.c:4242 in +__flush_work) occurs because the cleanup path tries to cancel an +uninitialized work queue. + +When __netpoll_setup() encounters a device with IFF_DISABLE_NETPOLL, +it fails early and calls skb_pool_flush() for cleanup. This function +calls cancel_work_sync(&np->refill_wq), but refill_wq hasn't been +initialized yet, triggering the warning. + +Move INIT_WORK() to the beginning of __netpoll_setup(), ensuring the +work queue is properly initialized before any potential failure points. +This allows the cleanup path to safely cancel the work queue regardless +of where the setup fails. + +Fixes: 248f6571fd4c5 ("netpoll: Optimize skb refilling on critical path") +Signed-off-by: Breno Leitao +Link: https://patch.msgid.link/20251127-netpoll_fix_init_work-v1-1-65c07806d736@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 be5658ff74ee2..27f573d2c5e36 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -554,6 +554,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) + int err; + + skb_queue_head_init(&np->skb_pool); ++ INIT_WORK(&np->refill_wq, refill_skbs_work_handler); + + if (ndev->priv_flags & IFF_DISABLE_NETPOLL) { + np_err(np, "%s doesn't support polling, aborting\n", +@@ -592,7 +593,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) + + /* fill up the skb queue */ + refill_skbs(np); +- INIT_WORK(&np->refill_wq, refill_skbs_work_handler); + + /* last thing to do is link it to the net device structure */ + rcu_assign_pointer(ndev->npinfo, npinfo); +-- +2.51.0 + diff --git a/queue-6.17/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch b/queue-6.17/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch new file mode 100644 index 0000000000..56b4fe4920 --- /dev/null +++ b/queue-6.17/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch @@ -0,0 +1,102 @@ +From 06375a2dfae2a7d438d9aa018fa3ff2ac2413f81 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 08:38:04 +0800 +Subject: net: phy: Add helper for fixing RGMII PHY mode based on internal mac + delay + +From: Inochi Amaoto + +[ Upstream commit 24afd7827efb7c69adfc41835390470e3eec4740 ] + +The "phy-mode" property of devicetree indicates whether the PCB has +delay now, which means the mac needs to modify the PHY mode based +on whether there is an internal delay in the mac. + +This modification is similar for many ethernet drivers. To simplify +code, define the helper phy_fix_phy_mode_for_mac_delays(speed, mac_txid, +mac_rxid) to fix PHY mode based on whether mac adds internal delay. + +Suggested-by: Russell King (Oracle) +Signed-off-by: Inochi Amaoto +Reviewed-by: Maxime Chevallier +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251114003805.494387-3-inochiama@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: db37c6e510de ("net: stmmac: dwmac-sophgo: Add phy interface filter") +Signed-off-by: Sasha Levin +--- + drivers/net/phy/phy-core.c | 43 ++++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 3 +++ + 2 files changed, 46 insertions(+) + +diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c +index 605ca20ae192d..0c63e6ba2cb0c 100644 +--- a/drivers/net/phy/phy-core.c ++++ b/drivers/net/phy/phy-core.c +@@ -101,6 +101,49 @@ const char *phy_rate_matching_to_str(int rate_matching) + } + EXPORT_SYMBOL_GPL(phy_rate_matching_to_str); + ++/** ++ * phy_fix_phy_mode_for_mac_delays - Convenience function for fixing PHY ++ * mode based on whether mac adds internal delay ++ * ++ * @interface: The current interface mode of the port ++ * @mac_txid: True if the mac adds internal tx delay ++ * @mac_rxid: True if the mac adds internal rx delay ++ * ++ * Return: fixed PHY mode, or PHY_INTERFACE_MODE_NA if the interface can ++ * not apply the internal delay ++ */ ++phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface, ++ bool mac_txid, bool mac_rxid) ++{ ++ if (!phy_interface_mode_is_rgmii(interface)) ++ return interface; ++ ++ if (mac_txid && mac_rxid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ if (mac_txid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII_RXID; ++ if (interface == PHY_INTERFACE_MODE_RGMII_TXID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ if (mac_rxid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII_TXID; ++ if (interface == PHY_INTERFACE_MODE_RGMII_RXID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ return interface; ++} ++EXPORT_SYMBOL_GPL(phy_fix_phy_mode_for_mac_delays); ++ + /** + * phy_interface_num_ports - Return the number of links that can be carried by + * a given MAC-PHY physical link. Returns 0 if this is +diff --git a/include/linux/phy.h b/include/linux/phy.h +index 04553419adc3f..2640ce96db3f3 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -1795,6 +1795,9 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev) + return phydev->is_pseudo_fixed_link; + } + ++phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface, ++ bool mac_txid, bool mac_rxid); ++ + int phy_save_page(struct phy_device *phydev); + int phy_select_page(struct phy_device *phydev, int page); + int phy_restore_page(struct phy_device *phydev, int oldpage, int ret); +-- +2.51.0 + diff --git a/queue-6.17/net-phy-adin1100-fix-software-power-down-ready-condi.patch b/queue-6.17/net-phy-adin1100-fix-software-power-down-ready-condi.patch new file mode 100644 index 0000000000..f272aac0ba --- /dev/null +++ b/queue-6.17/net-phy-adin1100-fix-software-power-down-ready-condi.patch @@ -0,0 +1,54 @@ +From d77a442b0deff7469df0d83a4387347213b61e02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:47:36 +0100 +Subject: net: phy: adin1100: Fix software power-down ready condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ] + +Value CRSM_SFT_PD written to Software Power-Down Control Register +(CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value +CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for +confirmation powerdown has been reached. + +The condition could have only worked when disabling powerdown +(both 0x00), but never when enabling it (0x01 != 0x02). + +Result is a timeout, like so: + + $ ifdown eth0 + macb f802c000.ethernet eth0: Link is Down + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + +Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") +Signed-off-by: Alexander Dahl +Reviewed-by: Russell King (Oracle) +Acked-by: Nuno Sá +Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/adin1100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c +index bd7a47a903aca..10b796c2daee7 100644 +--- a/drivers/net/phy/adin1100.c ++++ b/drivers/net/phy/adin1100.c +@@ -201,7 +201,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) + return ret; + + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, +- (ret & ADIN_CRSM_SFT_PD_RDY) == val, ++ !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, + 1000, 30000, true); + } + +-- +2.51.0 + diff --git a/queue-6.17/net-phy-aquantia-check-for-nvmem-deferral.patch b/queue-6.17/net-phy-aquantia-check-for-nvmem-deferral.patch new file mode 100644 index 0000000000..f525206ee4 --- /dev/null +++ b/queue-6.17/net-phy-aquantia-check-for-nvmem-deferral.patch @@ -0,0 +1,41 @@ +From 3117fbe29877eae1bb8a36e3a425570f8f41b8b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 12:44:35 +0100 +Subject: net: phy: aquantia: check for NVMEM deferral + +From: Robert Marko + +[ Upstream commit a6c121a2432eee2c4ebceb1483ccd4a50a52983d ] + +Currently, if NVMEM provider is probed later than Aquantia, loading the +firmware will fail with -EINVAL. + +To fix this, simply check for -EPROBE_DEFER when NVMEM is attempted and +return it. + +Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support") +Signed-off-by: Robert Marko +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251127114514.460924-1-robimarko@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/aquantia/aquantia_firmware.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c +index bbbcc9736b00e..569256152689f 100644 +--- a/drivers/net/phy/aquantia/aquantia_firmware.c ++++ b/drivers/net/phy/aquantia/aquantia_firmware.c +@@ -369,7 +369,7 @@ int aqr_firmware_load(struct phy_device *phydev) + * assume that, and load a new image. + */ + ret = aqr_firmware_load_nvmem(phydev); +- if (!ret) ++ if (ret == -EPROBE_DEFER || !ret) + return ret; + + ret = aqr_firmware_load_fs(phydev); +-- +2.51.0 + diff --git a/queue-6.17/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch b/queue-6.17/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch new file mode 100644 index 0000000000..072881d46a --- /dev/null +++ b/queue-6.17/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch @@ -0,0 +1,138 @@ +From d9367012d22b0e4c77a68f351187e88bc4fa2e01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 01:40:28 +0200 +Subject: net: phy: realtek: create rtl8211f_config_rgmii_delay() + +From: Vladimir Oltean + +[ Upstream commit 8e982441ba601d982dd0739972115d85ae01d99b ] + +The control flow in rtl8211f_config_init() has some pitfalls which were +probably unintended. Specifically it has an early return: + + switch (phydev->interface) { + ... + default: /* the rest of the modes imply leaving delay as is. */ + return 0; + } + +which exits the entire config_init() function. This means it also skips +doing things such as disabling CLKOUT or disabling PHY-mode EEE. + +For the RTL8211FS, which uses PHY_INTERFACE_MODE_SGMII, this might be a +problem. However, I don't know that it is, so there is no Fixes: tag. +The issue was observed through code inspection. + +Signed-off-by: Vladimir Oltean +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251117234033.345679-2-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/realtek/realtek_main.c | 65 +++++++++++++++----------- + 1 file changed, 39 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c +index 62ef87ecc5587..54a3faf5e6f57 100644 +--- a/drivers/net/phy/realtek/realtek_main.c ++++ b/drivers/net/phy/realtek/realtek_main.c +@@ -516,22 +516,11 @@ static int rtl8211c_config_init(struct phy_device *phydev) + CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER); + } + +-static int rtl8211f_config_init(struct phy_device *phydev) ++static int rtl8211f_config_rgmii_delay(struct phy_device *phydev) + { +- struct rtl821x_priv *priv = phydev->priv; +- struct device *dev = &phydev->mdio.dev; + u16 val_txdly, val_rxdly; + int ret; + +- ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, +- RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF, +- priv->phycr1); +- if (ret < 0) { +- dev_err(dev, "aldps mode configuration failed: %pe\n", +- ERR_PTR(ret)); +- return ret; +- } +- + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: + val_txdly = 0; +@@ -561,34 +550,58 @@ static int rtl8211f_config_init(struct phy_device *phydev) + RTL8211F_TXCR, RTL8211F_TX_DELAY, + val_txdly); + if (ret < 0) { +- dev_err(dev, "Failed to update the TX delay register\n"); ++ phydev_err(phydev, "Failed to update the TX delay register: %pe\n", ++ ERR_PTR(ret)); + return ret; + } else if (ret) { +- dev_dbg(dev, +- "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", +- str_enable_disable(val_txdly)); ++ phydev_dbg(phydev, ++ "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", ++ str_enable_disable(val_txdly)); + } else { +- dev_dbg(dev, +- "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", +- str_enabled_disabled(val_txdly)); ++ phydev_dbg(phydev, ++ "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", ++ str_enabled_disabled(val_txdly)); + } + + ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE, + RTL8211F_RXCR, RTL8211F_RX_DELAY, + val_rxdly); + if (ret < 0) { +- dev_err(dev, "Failed to update the RX delay register\n"); ++ phydev_err(phydev, "Failed to update the RX delay register: %pe\n", ++ ERR_PTR(ret)); + return ret; + } else if (ret) { +- dev_dbg(dev, +- "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n", +- str_enable_disable(val_rxdly)); ++ phydev_dbg(phydev, ++ "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n", ++ str_enable_disable(val_rxdly)); + } else { +- dev_dbg(dev, +- "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n", +- str_enabled_disabled(val_rxdly)); ++ phydev_dbg(phydev, ++ "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n", ++ str_enabled_disabled(val_rxdly)); + } + ++ return 0; ++} ++ ++static int rtl8211f_config_init(struct phy_device *phydev) ++{ ++ struct rtl821x_priv *priv = phydev->priv; ++ struct device *dev = &phydev->mdio.dev; ++ int ret; ++ ++ ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, ++ RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF, ++ priv->phycr1); ++ if (ret < 0) { ++ dev_err(dev, "aldps mode configuration failed: %pe\n", ++ ERR_PTR(ret)); ++ return ret; ++ } ++ ++ ret = rtl8211f_config_rgmii_delay(phydev); ++ if (ret) ++ return ret; ++ + if (!priv->has_phycr2) + return 0; + +-- +2.51.0 + diff --git a/queue-6.17/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-6.17/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..f77d3f497c --- /dev/null +++ b/queue-6.17/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From 23d48e23f00aa22345e83990a0b793eac1d08f36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 32bacfc314c26..d325a90cde9ee 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1597,7 +1597,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1743,14 +1742,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1823,6 +1822,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1833,13 +1834,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1848,11 +1849,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1927,24 +1928,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-6.17/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch b/queue-6.17/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch new file mode 100644 index 0000000000..66b40e5802 --- /dev/null +++ b/queue-6.17/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch @@ -0,0 +1,81 @@ +From 9ae5cb095d3f27f32bce044e2492b61ed73efab2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 08:38:05 +0800 +Subject: net: stmmac: dwmac-sophgo: Add phy interface filter + +From: Inochi Amaoto + +[ Upstream commit db37c6e510deabc9b0ee27c08f1c5aaa19f2e8ef ] + +As the SG2042 has an internal rx delay, the delay should be removed +when initializing the mac, otherwise the phy will be misconfigurated. + +Fixes: 543009e2d4cd ("net: stmmac: dwmac-sophgo: Add support for Sophgo SG2042 SoC") +Signed-off-by: Inochi Amaoto +Tested-by: Han Gao +Reviewed-by: Andrew Lunn +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251114003805.494387-4-inochiama@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/stmicro/stmmac/dwmac-sophgo.c | 20 ++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c +index 3b7947a7a7ba7..fcdda2401968b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c +@@ -7,11 +7,16 @@ + + #include + #include ++#include + #include + #include + + #include "stmmac_platform.h" + ++struct sophgo_dwmac_data { ++ bool has_internal_rx_delay; ++}; ++ + static int sophgo_sg2044_dwmac_init(struct platform_device *pdev, + struct plat_stmmacenet_data *plat_dat, + struct stmmac_resources *stmmac_res) +@@ -32,6 +37,7 @@ static int sophgo_sg2044_dwmac_init(struct platform_device *pdev, + static int sophgo_dwmac_probe(struct platform_device *pdev) + { + struct plat_stmmacenet_data *plat_dat; ++ const struct sophgo_dwmac_data *data; + struct stmmac_resources stmmac_res; + struct device *dev = &pdev->dev; + int ret; +@@ -50,11 +56,23 @@ static int sophgo_dwmac_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ data = device_get_match_data(&pdev->dev); ++ if (data && data->has_internal_rx_delay) { ++ plat_dat->phy_interface = phy_fix_phy_mode_for_mac_delays(plat_dat->phy_interface, ++ false, true); ++ if (plat_dat->phy_interface == PHY_INTERFACE_MODE_NA) ++ return -EINVAL; ++ } ++ + return stmmac_dvr_probe(dev, plat_dat, &stmmac_res); + } + ++static const struct sophgo_dwmac_data sg2042_dwmac_data = { ++ .has_internal_rx_delay = true, ++}; ++ + static const struct of_device_id sophgo_dwmac_match[] = { +- { .compatible = "sophgo,sg2042-dwmac" }, ++ { .compatible = "sophgo,sg2042-dwmac", .data = &sg2042_dwmac_data }, + { .compatible = "sophgo,sg2044-dwmac" }, + { /* sentinel */ } + }; +-- +2.51.0 + diff --git a/queue-6.17/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-6.17/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..41ac59557e --- /dev/null +++ b/queue-6.17/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From 0d02fd8d44003ae3349a52c92f9e6b2df4020ac3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 7a375de2258c4..abbd83f4c70f3 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5349,10 +5349,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-6.17/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch b/queue-6.17/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch new file mode 100644 index 0000000000..b5193ae3df --- /dev/null +++ b/queue-6.17/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch @@ -0,0 +1,60 @@ +From f98efb955e46b8087591d563343d0350b09c8ff4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 11:27:20 +0000 +Subject: net: stmmac: Fix VLAN 0 deletion in vlan_del_hw_rx_fltr() + +From: Ovidiu Panait + +[ Upstream commit d9db25723677c3741a0cf3643f7f7429fc983921 ] + +When the "rx-vlan-filter" feature is enabled on a network device, the 8021q +module automatically adds a VLAN 0 hardware filter when the device is +brought administratively up. + +For stmmac, this causes vlan_add_hw_rx_fltr() to create a new entry for +VID 0 in the mac_device_info->vlan_filter array, in the following format: + + VLAN_TAG_DATA_ETV | VLAN_TAG_DATA_VEN | vid + +Here, VLAN_TAG_DATA_VEN indicates that the hardware filter is enabled for +that VID. + +However, on the delete path, vlan_del_hw_rx_fltr() searches the vlan_filter +array by VID only, without verifying whether a VLAN entry is enabled. As a +result, when the 8021q module attempts to remove VLAN 0, the function may +mistakenly match a zero-initialized slot rather than the actual VLAN 0 +entry, causing incorrect deletions and leaving stale entries in the +hardware table. + +Fix this by verifying that the VLAN entry's enable bit (VLAN_TAG_DATA_VEN) +is set before matching and deleting by VID. This ensures only active VLAN +entries are removed and avoids leaving stale entries in the VLAN filter +table, particularly for VLAN ID 0. + +Fixes: ed64639bc1e08 ("net: stmmac: Add support for VLAN Rx filtering") +Signed-off-by: Ovidiu Panait +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20251113112721.70500-2-ovidiu.panait.rb@renesas.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +index 0b6f6228ae35d..fd97879a87408 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +@@ -122,7 +122,8 @@ static int vlan_del_hw_rx_fltr(struct net_device *dev, + + /* Extended Rx VLAN Filter Enable */ + for (i = 0; i < hw->num_vlan; i++) { +- if ((hw->vlan_filter[i] & VLAN_TAG_DATA_VID) == vid) { ++ if ((hw->vlan_filter[i] & VLAN_TAG_DATA_VEN) && ++ ((hw->vlan_filter[i] & VLAN_TAG_DATA_VID) == vid)) { + ret = vlan_write_filter(dev, hw, i, 0); + + if (!ret) +-- +2.51.0 + diff --git a/queue-6.17/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-6.17/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..05714801da --- /dev/null +++ b/queue-6.17/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From 451a60a6114f143f6c1bcec7dfe2803633553a78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 225ff293cd500..3e1e8c6de9aa2 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -141,12 +141,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-6.17/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-6.17/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..3c569f7f3d --- /dev/null +++ b/queue-6.17/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,503 @@ +From 9c53129b8d6916be59a3ead3bae3dbbe7ff8ceff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index 1b58b5b91ff6a..52a06de41aa0f 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -18,15 +18,14 @@ struct nf_conncount_list { + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen); + void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 913ede2f57f9a..0ffc5ff78a714 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if ((u32)jiffies == list->last_gc) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen) + { +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 92b984fa8175c..d998e27713ac7 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index 0189f8b6b0bd1..848287ab79cfb 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index e573e92213029..a0811e1fba656 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -928,8 +928,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -942,8 +942,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -972,8 +973,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -1770,8 +1770,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-6.17/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-6.17/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..55179869fb --- /dev/null +++ b/queue-6.17/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From dfd8e74e8a0962ae65c9092fd9fcfa098b41c941 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 0ffc5ff78a714..b84cfb5616df4 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if ((u32)jiffies == list->last_gc) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index d998e27713ac7..83a7d5769396c 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-6.17/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-6.17/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..0cf461ad9e --- /dev/null +++ b/queue-6.17/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From ccd11d6f35caeb23f2213e754a6a81ee86a75673 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index 0822d8a119c6f..eefe50a17c4a0 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -53,7 +54,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-6.17/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-6.17/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..3d4b344447 --- /dev/null +++ b/queue-6.17/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From 0e8f7a92ebb56590bf81f6c0f2eec44a76ba904d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index b08b009121653..cf7e869fdc40c 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1717,6 +1717,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-6.17/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-6.17/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..1042aa7b59 --- /dev/null +++ b/queue-6.17/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From 555d4b475ce05a596f6917cc049ccc1c28798f19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index c7a2f191254da..5ae910e9ecbda 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1349,7 +1349,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-6.17/ntfs3-init-run-lock-for-extend-inode.patch b/queue-6.17/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..8194097535 --- /dev/null +++ b/queue-6.17/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From 1b8e79a926ae1ce8a4ea560823751f25674533d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index cf7e869fdc40c..d085bc4370348 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -472,6 +472,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-6.17/objtool-fix-standalone-hacks-jump_label.patch b/queue-6.17/objtool-fix-standalone-hacks-jump_label.patch new file mode 100644 index 0000000000..6682edac2a --- /dev/null +++ b/queue-6.17/objtool-fix-standalone-hacks-jump_label.patch @@ -0,0 +1,44 @@ +From 1fdc6848e3a80e37bb7552e25e287597ddecbb3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 00:49:41 +0000 +Subject: objtool: Fix standalone --hacks=jump_label + +From: Dylan Hatch + +[ Upstream commit be8374a5ba7cbab6b97df94b4ffe0b92f5c8a6d2 ] + +The objtool command line 'objtool --hacks=jump_label foo.o' on its own +should be expected to rewrite jump labels to NOPs. This means the +add_special_section_alts() code path needs to run when only this option +is provided. + +This is mainly relevant in certain debugging situations, but could +potentially also fix kernel builds in which objtool is run with +--hacks=jump_label but without --orc, --stackval, --uaccess, or +--hacks=noinstr. + +Fixes: de6fbcedf5ab ("objtool: Read special sections with alts only when specific options are selected") +Signed-off-by: Dylan Hatch +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index d23fefcb15d38..ac2b8813c4a0a 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2563,7 +2563,8 @@ static int decode_sections(struct objtool_file *file) + * Must be before add_jump_destinations(), which depends on 'func' + * being set for alternatives, to enable proper sibling call detection. + */ +- if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { ++ if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || ++ opts.hack_jump_label) { + ret = add_special_section_alts(file); + if (ret) + return ret; +-- +2.51.0 + diff --git a/queue-6.17/objtool-fix-weak-symbol-detection.patch b/queue-6.17/objtool-fix-weak-symbol-detection.patch new file mode 100644 index 0000000000..8d7fab07b7 --- /dev/null +++ b/queue-6.17/objtool-fix-weak-symbol-detection.patch @@ -0,0 +1,65 @@ +From 9c7044283e8c6607d6c80bfba751e5b0766ff438 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:27 -0700 +Subject: objtool: Fix weak symbol detection + +From: Josh Poimboeuf + +[ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] + +find_symbol_hole_containing() fails to find a symbol hole (aka stripped +weak symbol) if its section has no symbols before the hole. This breaks +weak symbol detection if -ffunction-sections is enabled. + +Fix that by allowing the interval tree to contain section symbols, which +are always at offset zero for a given section. + +Fixes a bunch of (-ffunction-sections) warnings like: + + vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction + +Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") +Acked-by: Petr Mladek +Tested-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index ca5d77db692a2..9cb51fcde7986 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -108,7 +108,7 @@ struct symbol_hole { + }; + + /* +- * Find !section symbol where @offset is after it. ++ * Find the last symbol before @offset. + */ + static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + { +@@ -119,8 +119,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + return -1; + + if (sh->key >= s->offset + s->len) { +- if (s->type != STT_SECTION) +- sh->sym = s; ++ sh->sym = s; + return 1; + } + +@@ -412,7 +411,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->len = sym->sym.st_size; + + __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { +- if (iter->offset == sym->offset && iter->type == sym->type) ++ if (iter->offset == sym->offset && iter->type == sym->type && ++ iter->len == sym->len) + iter->alias = sym; + } + +-- +2.51.0 + diff --git a/queue-6.17/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-6.17/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..2602aac57d --- /dev/null +++ b/queue-6.17/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From 508257ca582333c63c0fe0ca32b6ec2670b4ab94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 80ebb0b7265a9..5a0228c51ec3c 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-6.17/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch b/queue-6.17/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch new file mode 100644 index 0000000000..f47c54088b --- /dev/null +++ b/queue-6.17/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch @@ -0,0 +1,54 @@ +From 27c64267b2f8c58bef9ea11d90d80144751599eb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 20:32:17 +0800 +Subject: ocfs2: use correct endian in ocfs2_dinode_has_extents + +From: Joseph Qi + +[ Upstream commit c9dff86eb78a4b6b02b1e407993c946ccaf9bfb4 ] + +Fields in ocfs2_dinode is little endian, covert to host endian when +checking those contents. + +Link: https://lkml.kernel.org/r/20251025123218.3997866-1-joseph.qi@linux.alibaba.com +Fixes: fdbb6cd96ed5 ("ocfs2: correct l_next_free_rec in online check") +Signed-off-by: Joseph Qi +Reviewed-by: Heming Zhao +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/inode.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c +index 6c4f78f473fb4..d4ca824f9c82b 100644 +--- a/fs/ocfs2/inode.c ++++ b/fs/ocfs2/inode.c +@@ -201,13 +201,15 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, + static int ocfs2_dinode_has_extents(struct ocfs2_dinode *di) + { + /* inodes flagged with other stuff in id2 */ +- if (di->i_flags & (OCFS2_SUPER_BLOCK_FL | OCFS2_LOCAL_ALLOC_FL | +- OCFS2_CHAIN_FL | OCFS2_DEALLOC_FL)) ++ if (le32_to_cpu(di->i_flags) & ++ (OCFS2_SUPER_BLOCK_FL | OCFS2_LOCAL_ALLOC_FL | OCFS2_CHAIN_FL | ++ OCFS2_DEALLOC_FL)) + return 0; + /* i_flags doesn't indicate when id2 is a fast symlink */ +- if (S_ISLNK(di->i_mode) && di->i_size && di->i_clusters == 0) ++ if (S_ISLNK(le16_to_cpu(di->i_mode)) && le64_to_cpu(di->i_size) && ++ !le32_to_cpu(di->i_clusters)) + return 0; +- if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) ++ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) + return 0; + + return 1; +-- +2.51.0 + diff --git a/queue-6.17/of-fdt-consolidate-duplicate-code-into-helper-functi.patch b/queue-6.17/of-fdt-consolidate-duplicate-code-into-helper-functi.patch new file mode 100644 index 0000000000..3282572c43 --- /dev/null +++ b/queue-6.17/of-fdt-consolidate-duplicate-code-into-helper-functi.patch @@ -0,0 +1,98 @@ +From 81e78d25a099014671c05f333a09597b31256b8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:46 +0800 +Subject: of/fdt: Consolidate duplicate code into helper functions + +From: Yuntao Wang + +[ Upstream commit 8278cb72c60399f6dc6300c409879fb4c7291513 ] + +Currently, there are many pieces of nearly identical code scattered across +different places. Consolidate the duplicate code into helper functions to +improve maintainability and reduce the likelihood of errors. + +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-2-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Stable-dep-of: c85da64ce2c3 ("of/fdt: Fix incorrect use of dt_root_addr_cells in early_init_dt_check_kho()") +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 41 +++++++++++++++++++++++++++++++++++++++++ + include/linux/of_fdt.h | 9 +++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 0edd639898a63..0c18bdefbbeea 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -625,6 +625,47 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + return fdt_getprop(initial_boot_params, node, name, size); + } + ++const __be32 *__init of_flat_dt_get_addr_size_prop(unsigned long node, ++ const char *name, ++ int *entries) ++{ ++ const __be32 *prop; ++ int len, elen = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); ++ ++ prop = of_get_flat_dt_prop(node, name, &len); ++ if (!prop || len % elen) { ++ *entries = 0; ++ return NULL; ++ } ++ ++ *entries = len / elen; ++ return prop; ++} ++ ++bool __init of_flat_dt_get_addr_size(unsigned long node, const char *name, ++ u64 *addr, u64 *size) ++{ ++ const __be32 *prop; ++ int entries; ++ ++ prop = of_flat_dt_get_addr_size_prop(node, name, &entries); ++ if (!prop || entries != 1) ++ return false; ++ ++ of_flat_dt_read_addr_size(prop, 0, addr, size); ++ return true; ++} ++ ++void __init of_flat_dt_read_addr_size(const __be32 *prop, int entry_index, ++ u64 *addr, u64 *size) ++{ ++ int entry_cells = dt_root_addr_cells + dt_root_size_cells; ++ prop += entry_cells * entry_index; ++ ++ *addr = dt_mem_next_cell(dt_root_addr_cells, &prop); ++ *size = dt_mem_next_cell(dt_root_size_cells, &prop); ++} ++ + /** + * of_fdt_is_compatible - Return true if given node from the given blob has + * compat in its compatible list +diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h +index b8d6c0c208760..51dadbaa3d63a 100644 +--- a/include/linux/of_fdt.h ++++ b/include/linux/of_fdt.h +@@ -55,6 +55,15 @@ extern int of_get_flat_dt_subnode_by_name(unsigned long node, + const char *uname); + extern const void *of_get_flat_dt_prop(unsigned long node, const char *name, + int *size); ++ ++extern const __be32 *of_flat_dt_get_addr_size_prop(unsigned long node, ++ const char *name, ++ int *entries); ++extern bool of_flat_dt_get_addr_size(unsigned long node, const char *name, ++ u64 *addr, u64 *size); ++extern void of_flat_dt_read_addr_size(const __be32 *prop, int entry_index, ++ u64 *addr, u64 *size); ++ + extern int of_flat_dt_is_compatible(unsigned long node, const char *name); + extern unsigned long of_get_flat_dt_root(void); + extern uint32_t of_get_flat_dt_phandle(unsigned long node); +-- +2.51.0 + diff --git a/queue-6.17/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch b/queue-6.17/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch new file mode 100644 index 0000000000..cac5a8b73c --- /dev/null +++ b/queue-6.17/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch @@ -0,0 +1,64 @@ +From 67c118f7851cb7c4a355f52024a346fe4b14814c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:49 +0800 +Subject: of/fdt: Fix incorrect use of dt_root_addr_cells in + early_init_dt_check_kho() + +From: Yuntao Wang + +[ Upstream commit c85da64ce2c36bba469f6feede9ca768f0361741 ] + +When reading the fdt_size value, the argument passed to dt_mem_next_cell() +is dt_root_addr_cells, but it should be dt_root_size_cells. + +The same issue occurs when reading the scratch_size value. + +Use a helper function to simplify the code and fix these issues. + +Fixes: 274cdcb1c004 ("arm64: add KHO support") +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-5-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 0c18bdefbbeea..de16785a48695 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -924,26 +924,18 @@ static void __init early_init_dt_check_kho(void) + { + unsigned long node = chosen_node_offset; + u64 fdt_start, fdt_size, scratch_start, scratch_size; +- const __be32 *p; +- int l; + + if (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node < 0) + return; + +- p = of_get_flat_dt_prop(node, "linux,kho-fdt", &l); +- if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) ++ if (!of_flat_dt_get_addr_size(node, "linux,kho-fdt", ++ &fdt_start, &fdt_size)) + return; + +- fdt_start = dt_mem_next_cell(dt_root_addr_cells, &p); +- fdt_size = dt_mem_next_cell(dt_root_addr_cells, &p); +- +- p = of_get_flat_dt_prop(node, "linux,kho-scratch", &l); +- if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) ++ if (!of_flat_dt_get_addr_size(node, "linux,kho-scratch", ++ &scratch_start, &scratch_size)) + return; + +- scratch_start = dt_mem_next_cell(dt_root_addr_cells, &p); +- scratch_size = dt_mem_next_cell(dt_root_addr_cells, &p); +- + kho_populate(fdt_start, fdt_size, scratch_start, scratch_size); + } + +-- +2.51.0 + diff --git a/queue-6.17/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch b/queue-6.17/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch new file mode 100644 index 0000000000..f08dca2eb3 --- /dev/null +++ b/queue-6.17/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch @@ -0,0 +1,60 @@ +From 1cbf0bafa99f6711e557aebcfa7a347c8558e599 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:04:14 -0700 +Subject: of: Skip devicetree kunit tests when RISCV+ACPI doesn't populate root + node + +From: Guenter Roeck + +[ Upstream commit 546dbb0223102813ffb5bbcb9443a47c3183f195 ] + +Starting with commit 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by +probing DT devices when ACPI is used"), riscv images no longer populate +devicetree if ACPI is enabled. This causes unit tests to fail which require +the root node to be set. + + # Subtest: of_dtb + # module: of_test + 1..2 + # of_dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:21 + Expected np is not null, but is + # of_dtb_root_node_found_by_path: pass:0 fail:1 skip:0 total:1 + not ok 1 of_dtb_root_node_found_by_path + # of_dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:31 + Expected of_root is not null, but is + # of_dtb_root_node_populates_of_root: pass:0 fail:1 skip:0 total:1 + not ok 2 of_dtb_root_node_populates_of_root + +Skip those tests for RISCV if the root node is not populated. + +Fixes: 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by probing DT devices when ACPI is used") +Cc: Han Gao +Cc: Paul Walmsley +Signed-off-by: Guenter Roeck +Reviewed-by: Paul Walmsley # arch/riscv +Link: https://patch.msgid.link/20251023160415.705294-1-linux@roeck-us.net +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/of_kunit_helpers.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/of/of_kunit_helpers.c b/drivers/of/of_kunit_helpers.c +index 7b3ed5a382aaa..f6ed1af8b62aa 100644 +--- a/drivers/of/of_kunit_helpers.c ++++ b/drivers/of/of_kunit_helpers.c +@@ -18,8 +18,9 @@ + */ + void of_root_kunit_skip(struct kunit *test) + { +- if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root) +- kunit_skip(test, "arm64+acpi doesn't populate a root node"); ++ if ((IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_RISCV)) && ++ IS_ENABLED(CONFIG_ACPI) && !of_root) ++ kunit_skip(test, "arm64/riscv+acpi doesn't populate a root node"); + } + EXPORT_SYMBOL_GPL(of_root_kunit_skip); + +-- +2.51.0 + diff --git a/queue-6.17/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-6.17/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..95c20d113d --- /dev/null +++ b/queue-6.17/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From 3c4e5a2c96f0a54267b4d68801549781c4115942 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index cc71a2d90cd48..509e08e58b692 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -95,7 +95,7 @@ + #define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-6.17/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch b/queue-6.17/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch new file mode 100644 index 0000000000..4f068145d2 --- /dev/null +++ b/queue-6.17/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch @@ -0,0 +1,62 @@ +From 0bc3cede8f034b35da2c3ea14d4f169e18ffa243 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 08:11:09 +0530 +Subject: PCI: endpoint: pci-epf-test: Fix sleeping function being called from + atomic context + +From: Bhanu Seshu Kumar Valluri + +[ Upstream commit 25423cda145f9ed6ee4a72d9f2603ac2a4685e74 ] + +When Root Complex (RC) triggers a Doorbell interrupt to Endpoint (EP), it +triggers the below warning in the EP: + + BUG: sleeping function called from invalid context at kernel/locking/mutex.c:271 + Call trace: + __might_resched+0x130/0x158 + __might_sleep+0x70/0x88 + mutex_lock+0x2c/0x80 + pci_epc_get_msi+0x78/0xd8 + pci_epf_test_raise_irq.isra.0+0x74/0x138 + pci_epf_test_doorbell_handler+0x34/0x50 + +The BUG arises because the EP's pci_epf_test_doorbell_handler() which is +running in the hard IRQ context is making an indirect call to +pci_epc_get_msi(), which uses mutex inside. + +To fix the issue, convert the hard IRQ handler to a threaded IRQ handler to +allow it to call functions that can sleep during bottom half execution. +Also, register the threaded IRQ handler with IRQF_ONESHOT to keep the +interrupt line disabled until the threaded IRQ handler completes execution. + +Fixes: eff0c286aa91 ("PCI: endpoint: pci-epf-test: Add doorbell test support") +Signed-off-by: Bhanu Seshu Kumar Valluri +[mani: reworded description a bit] +Signed-off-by: Manivannan Sadhasivam +Reviewed-by: Niklas Cassel +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20251014024109.42287-1-bhanuseshukumar@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/functions/pci-epf-test.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 31617772ad516..b05e8db575c35 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -730,8 +730,9 @@ static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test, + if (bar < BAR_0) + goto err_doorbell_cleanup; + +- ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0, +- "pci-ep-test-doorbell", epf_test); ++ ret = request_threaded_irq(epf->db_msg[0].virq, NULL, ++ pci_epf_test_doorbell_handler, IRQF_ONESHOT, ++ "pci-ep-test-doorbell", epf_test); + if (ret) { + dev_err(&epf->dev, + "Failed to request doorbell IRQ: %d\n", +-- +2.51.0 + diff --git a/queue-6.17/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-6.17/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..a684c72f67 --- /dev/null +++ b/queue-6.17/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 64e73c60a398191a7ad5666ed7058b07cc7f45c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 21808a9e51586..ed0f6cf3df6b2 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1338,6 +1338,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-6.17/pci-prevent-resource-tree-corruption-when-bar-resize.patch b/queue-6.17/pci-prevent-resource-tree-corruption-when-bar-resize.patch new file mode 100644 index 0000000000..49fdc8016f --- /dev/null +++ b/queue-6.17/pci-prevent-resource-tree-corruption-when-bar-resize.patch @@ -0,0 +1,74 @@ +From 016ab284ced6756bf0e8559788fcae39bfad9faf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:26:18 +0200 +Subject: PCI: Prevent resource tree corruption when BAR resize fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 91c4c89db41499eea1b29c56655f79c3bae66e93 ] + +pbus_reassign_bridge_resources() saves bridge windows into the saved +list before attempting to adjust resource assignments to perform a BAR +resize operation. If resource adjustments cannot be completed fully, +rollback is attempted by restoring the resource from the saved list. + +The rollback, however, does not check whether the resources it restores were +assigned by the partial resize attempt. If restore changes addresses of the +resource, it can result in corrupting the resource tree. + +An example of a corrupted resource tree with overlapping addresses: + + 6200000000000-6203fbfffffff : pciex@620c3c0000000 + 6200000000000-6203fbff0ffff : PCI Bus 0030:01 + 6200020000000-62000207fffff : 0030:01:00.0 + 6200000000000-6203fbff0ffff : PCI Bus 0030:02 + +A resource that are assigned into the resource tree must remain +unchanged. Thus, release such a resource before attempting to restore +and claim it back. + +For simplicity, always do the release and claim back for the resource +even in the cases where it is restored to the same address range. + +Note: this fix may "break" some cases where devices "worked" because +the resource tree corruption allowed address space double counting to +fit more resource than what can now be assigned without double +counting. The upcoming changes to BAR resizing should address those +scenarios (to the extent possible). + +Fixes: 8bb705e3e79d ("PCI: Add pci_resize_resource() for resizing BARs") +Reported-by: Simon Richter +Link: https://lore.kernel.org/linux-pci/67840a16-99b4-4d8c-9b5c-4721ab0970a2@hogyros.de/ +Reported-by: Alex Bennée +Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/ +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Tested-by: Alex Bennée # AVA, AMD GPU +Link: https://patch.msgid.link/20251113162628.5946-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/pci/setup-bus.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index 77a566aeae601..bca00d7ce3ce0 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -2489,6 +2489,11 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type) + bridge = dev_res->dev; + i = pci_resource_num(bridge, res); + ++ if (res->parent) { ++ release_child_resources(res); ++ pci_release_resource(bridge, i); ++ } ++ + restore_dev_resource(dev_res); + + pci_claim_resource(bridge, i); +-- +2.51.0 + diff --git a/queue-6.17/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch b/queue-6.17/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch new file mode 100644 index 0000000000..5a87bee59f --- /dev/null +++ b/queue-6.17/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch @@ -0,0 +1,55 @@ +From 32607c194d5a9fa74f4ee11aa8eb7e41ca6be3f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 10:35:34 +0200 +Subject: PCI: rcar-gen2: Drop ARM dependency from PCI_RCAR_GEN2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit d312742f686582e6457070bcfd24bee8acfdf213 ] + +Since the reliance on ARM-specific struct pci_sys_data was removed, this +driver can be compile-tested on other architectures. + +While at it, make the help text a bit more generic, as some members of +the R-Car Gen2 family have a different number of internal PCI +controllers. + +Fixes: 4a957563fe0231e0 ("PCI: rcar-gen2: Convert to use modern host bridge probe functions") +Suggested-by: Ilpo Jarvinen +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: add rcar-gen2 to subject] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/00f75d6732eacce93f04ffaeedc415d2db714cd6.1759480426.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/Kconfig | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 41748d083b933..0452151a7bccc 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -259,12 +259,11 @@ config PCIE_RCAR_EP + + config PCI_RCAR_GEN2 + bool "Renesas R-Car Gen2 Internal PCI controller" +- depends on ARCH_RENESAS || COMPILE_TEST +- depends on ARM ++ depends on (ARCH_RENESAS && ARM) || COMPILE_TEST + help + Say Y here if you want internal PCI support on R-Car Gen2 SoC. +- There are 3 internal PCI controllers available with a single +- built-in EHCI/OHCI host controller present on each one. ++ Each internal PCI controller contains a single built-in EHCI/OHCI ++ host controller. + + config PCIE_ROCKCHIP + bool +-- +2.51.0 + diff --git a/queue-6.17/perf-annotate-check-return-value-of-evsel__get_arch-.patch b/queue-6.17/perf-annotate-check-return-value-of-evsel__get_arch-.patch new file mode 100644 index 0000000000..0af6d56adf --- /dev/null +++ b/queue-6.17/perf-annotate-check-return-value-of-evsel__get_arch-.patch @@ -0,0 +1,39 @@ +From cfc96131c1caa89bb0681e952d6c20726472f206 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 15:30:05 +0800 +Subject: perf annotate: Check return value of evsel__get_arch() properly + +From: Tianyou Li + +[ Upstream commit f1204e5846d22fb2fffbd1164eeb19535f306797 ] + +Check the error code of evsel__get_arch() in the symbol__annotate(). +Previously it checked non-zero value but after the refactoring it does +only for negative values. + +Fixes: 0669729eb0afb0cf ("perf annotate: Factor out evsel__get_arch()") +Suggested-by: James Clark +Acked-by: Namhyung Kim +Signed-off-by: Tianyou Li +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/annotate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c +index 0dd475a744b6d..3c3fb8c2a36d8 100644 +--- a/tools/perf/util/annotate.c ++++ b/tools/perf/util/annotate.c +@@ -1020,7 +1020,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, + int err, nr; + + err = evsel__get_arch(evsel, &arch); +- if (err < 0) ++ if (err) + return err; + + if (parch) +-- +2.51.0 + diff --git a/queue-6.17/perf-arm_spe-fix-memset-subclass-in-operation.patch b/queue-6.17/perf-arm_spe-fix-memset-subclass-in-operation.patch new file mode 100644 index 0000000000..de369449c6 --- /dev/null +++ b/queue-6.17/perf-arm_spe-fix-memset-subclass-in-operation.patch @@ -0,0 +1,99 @@ +From a163e4572ea413bbdad04d1d63da78d9add0576e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 18:24:27 +0000 +Subject: perf arm_spe: Fix memset subclass in operation + +From: Leo Yan + +[ Upstream commit 33e1fffea492b7158a168914dc0da6aedf78d08e ] + +The operation subclass is extracted from bits [7..1] of the payload. +Since bit [0] is not parsed, there is no chance to match the memset type +(0x25). As a result, the memset payload is never parsed successfully. + +Instead of extracting a unified bit field, change to extract the +specific bits for each operation subclass. + +Fixes: 34fb60400e32 ("perf arm-spe: Add raw decoding for SPEv1.3 MTE and MOPS load/store") +Signed-off-by: Leo Yan +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 ++++++------------- + .../arm-spe-decoder/arm-spe-pkt-decoder.h | 15 ++++++----- + 2 files changed, 14 insertions(+), 26 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index 13cadb2f1ceac..3c4ef5381c76c 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -357,31 +357,20 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR"); + } + +- switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) { +- case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP: ++ if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_GP_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMSET: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET"); +- break; +- default: +- break; +- } + + if (SPE_OP_PKT_IS_LDST_SVE(payload)) { + /* SVE effective vector length */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index 2cdf9f6da2681..51d5d038f620f 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -118,14 +118,13 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) +-#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 +-#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +-#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10 +-#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30 +-#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG 0x14 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY 0x20 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET 0x25 ++#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x0) ++#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(v) (((v) & GENMASK_ULL(7, 1)) == 0x4) ++#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x10) ++#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(v) (((v) & GENMASK_ULL(7, 1)) == 0x30) ++#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(v) (((v) & GENMASK_ULL(7, 1)) == 0x14) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(v) (((v) & GENMASK_ULL(7, 1)) == 0x20) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET(v) (((v) & GENMASK_ULL(7, 0)) == 0x25) + + #define SPE_OP_PKT_IS_LDST_ATOMIC(v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2) + +-- +2.51.0 + diff --git a/queue-6.17/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch b/queue-6.17/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch new file mode 100644 index 0000000000..09558b493e --- /dev/null +++ b/queue-6.17/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch @@ -0,0 +1,84 @@ +From ad524bb5a68284789a8b87ac820a401ae7f03bd8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 06:29:11 -0700 +Subject: perf bpf_counter: Fix opening of "any"(-1) CPU events + +From: Ian Rogers + +[ Upstream commit 2a67955de13624ec17d1c2504d2c9eeb37933b77 ] + +The bperf BPF counter code doesn't handle "any"(-1) CPU events, always +wanting to aggregate a count against a CPU, which avoids the need for +atomics so let's not change that. Force evsels used for BPF counters +to require a CPU when not in system-wide mode so that the "any"(-1) +value isn't used during map propagation and evsel's CPU map matches +that of the PMU. + +Fixes: b91917c0c6fa ("perf bpf_counter: Fix handling of cpumap fixing hybrid") +Signed-off-by: Ian Rogers +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-stat.c | 13 +++++++++++++ + tools/perf/util/bpf_counter.c | 7 ++++++- + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c +index 2c38dd98f6cae..64af743bb10a4 100644 +--- a/tools/perf/builtin-stat.c ++++ b/tools/perf/builtin-stat.c +@@ -2511,6 +2511,7 @@ int cmd_stat(int argc, const char **argv) + unsigned int interval, timeout; + const char * const stat_subcommands[] = { "record", "report" }; + char errbuf[BUFSIZ]; ++ struct evsel *counter; + + setlocale(LC_ALL, ""); + +@@ -2768,6 +2769,18 @@ int cmd_stat(int argc, const char **argv) + + evlist__warn_user_requested_cpus(evsel_list, target.cpu_list); + ++ evlist__for_each_entry(evsel_list, counter) { ++ /* ++ * Setup BPF counters to require CPUs as any(-1) isn't ++ * supported. evlist__create_maps below will propagate this ++ * information to the evsels. Note, evsel__is_bperf isn't yet ++ * set up, and this change must happen early, so directly use ++ * the bpf_counter variable and target information. ++ */ ++ if ((counter->bpf_counter || target.use_bpf) && !target__has_cpu(&target)) ++ counter->core.requires_cpu = true; ++ } ++ + if (evlist__create_maps(evsel_list, &target) < 0) { + if (target__has_task(&target)) { + pr_err("Problems finding threads of monitor\n"); +diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c +index ed88ba570c80a..af31aa28ff445 100644 +--- a/tools/perf/util/bpf_counter.c ++++ b/tools/perf/util/bpf_counter.c +@@ -402,6 +402,7 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd, + struct bperf_leader_bpf *skel = bperf_leader_bpf__open(); + int link_fd, diff_map_fd, err; + struct bpf_link *link = NULL; ++ struct perf_thread_map *threads; + + if (!skel) { + pr_err("Failed to open leader skeleton\n"); +@@ -437,7 +438,11 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd, + * following evsel__open_per_cpu call + */ + evsel->leader_skel = skel; +- evsel__open(evsel, evsel->core.cpus, evsel->core.threads); ++ assert(!perf_cpu_map__has_any_cpu_or_is_empty(evsel->core.cpus)); ++ /* Always open system wide. */ ++ threads = thread_map__new_by_tid(-1); ++ evsel__open(evsel, evsel->core.cpus, threads); ++ perf_thread_map__put(threads); + + out: + bperf_leader_bpf__destroy(skel); +-- +2.51.0 + diff --git a/queue-6.17/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch b/queue-6.17/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch new file mode 100644 index 0000000000..7ad83999ed --- /dev/null +++ b/queue-6.17/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch @@ -0,0 +1,42 @@ +From 1a7ba29c4fa19bb6c171ea5d046ce93f9f11a9a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 00:19:18 -0800 +Subject: perf hist: In init, ensure mem_info is put on error paths + +From: Ian Rogers + +[ Upstream commit f60efb4454b24cc944ff3eac164bb9dce9169f71 ] + +Rather than exit the internal map_symbols directly, put the mem-info +that does this and also lowers the reference count on the mem-info +itself otherwise the mem-info is being leaked. + +Fixes: 56e144fe98260a0f ("perf mem_info: Add and use map_symbol__exit and addr_map_symbol__exit") +Signed-off-by: Ian Rogers +Reviewed-by: Arnaldo Carvalho de Melo +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hist.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c +index 64ff427040c34..ef4b569f7df46 100644 +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -608,10 +608,8 @@ static int hist_entry__init(struct hist_entry *he, + map_symbol__exit(&he->branch_info->to.ms); + zfree(&he->branch_info); + } +- if (he->mem_info) { +- map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms); +- map_symbol__exit(&mem_info__daddr(he->mem_info)->ms); +- } ++ if (he->mem_info) ++ mem_info__zput(he->mem_info); + err: + map_symbol__exit(&he->ms); + zfree(&he->stat_acc); +-- +2.51.0 + diff --git a/queue-6.17/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch b/queue-6.17/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch new file mode 100644 index 0000000000..9be3fc01c9 --- /dev/null +++ b/queue-6.17/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch @@ -0,0 +1,46 @@ +From a55225f6ee41b4b6f9c270b9490cbecd570abbb4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 12:38:35 +0200 +Subject: perf hwmon_pmu: Fix uninitialized variable warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Suchanek + +[ Upstream commit 2fee899c068c159e486e62623afe9e2a4975bd79 ] + +The line_len is only set on success. Check the return value instead. + + util/hwmon_pmu.c: In function ‘perf_pmus__read_hwmon_pmus’: + util/hwmon_pmu.c:742:20: warning: ‘line_len’ may be used uninitialized [-Wmaybe-uninitialized] + 742 | if (line_len > 0 && line[line_len - 1] == '\n') + | ^ + util/hwmon_pmu.c:719:24: note: ‘line_len’ was declared here + 719 | size_t line_len; + +Fixes: 53cc0b351ec9 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs") +Signed-off-by: Michal Suchanek +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hwmon_pmu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c +index 416dfea9ffff6..5c27256a220a5 100644 +--- a/tools/perf/util/hwmon_pmu.c ++++ b/tools/perf/util/hwmon_pmu.c +@@ -742,8 +742,7 @@ int perf_pmus__read_hwmon_pmus(struct list_head *pmus) + continue; + } + io__init(&io, name_fd, buf2, sizeof(buf2)); +- io__getline(&io, &line, &line_len); +- if (line_len > 0 && line[line_len - 1] == '\n') ++ if (io__getline(&io, &line, &line_len) > 0 && line[line_len - 1] == '\n') + line[line_len - 1] = '\0'; + hwmon_pmu__new(pmus, buf, class_hwmon_ent->d_name, line); + close(name_fd); +-- +2.51.0 + diff --git a/queue-6.17/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch b/queue-6.17/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch new file mode 100644 index 0000000000..1929497fb3 --- /dev/null +++ b/queue-6.17/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch @@ -0,0 +1,122 @@ +From c9b5f14714c2f761fd2181ae4e6d43a601594848 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 00:07:46 -0800 +Subject: perf jitdump: Add sym/str-tables to build-ID generation + +From: Namhyung Kim + +[ Upstream commit 25d498e636d1f8d138d65246cfb5b1fc3069ca56 ] + +It was reported that python backtrace with JIT dump was broken after the +change to built-in SHA-1 implementation. It seems python generates the +same JIT code for each function. They will become separate DSOs but the +contents are the same. Only difference is in the symbol name. + +But this caused a problem that every JIT'ed DSOs will have the same +build-ID which makes perf confused. And it resulted in no python +symbols (from JIT) in the output. + +Looking back at the original code before the conversion, it used the +load_addr as well as the code section to distinguish each DSO. But it'd +be better to use contents of symtab and strtab instead as it aligns with +some linker behaviors. + +This patch adds a buffer to save all the contents in a single place for +SHA-1 calculation. Probably we need to add sha1_update() or similar to +update the existing hash value with different contents and use it here. +But it's out of scope for this change and I'd like something that can be +backported to the stable trees easily. + +Reviewed-by: Ian Rogers +Cc: Eric Biggers +Cc: Pablo Galindo +Cc: Fangrui Song +Link: https://github.com/python/cpython/issues/139544 +Fixes: e3f612c1d8f3945b ("perf genelf: Remove libcrypto dependency and use built-in sha1()") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/genelf.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c +index 591548b10e34e..a1cd5196f4ec8 100644 +--- a/tools/perf/util/genelf.c ++++ b/tools/perf/util/genelf.c +@@ -173,6 +173,8 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + Elf_Shdr *shdr; + uint64_t eh_frame_base_offset; + char *strsym = NULL; ++ void *build_id_data = NULL, *tmp; ++ int build_id_data_len; + int symlen; + int retval = -1; + +@@ -251,6 +253,14 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC; + shdr->sh_entsize = 0; + ++ build_id_data = malloc(csize); ++ if (build_id_data == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(build_id_data, code, csize); ++ build_id_data_len = csize; ++ + /* + * Setup .eh_frame_hdr and .eh_frame + */ +@@ -334,6 +344,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_entsize = sizeof(Elf_Sym); + shdr->sh_link = unwinding ? 6 : 4; /* index of .strtab section */ + ++ tmp = realloc(build_id_data, build_id_data_len + sizeof(symtab)); ++ if (tmp == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(tmp + build_id_data_len, symtab, sizeof(symtab)); ++ build_id_data = tmp; ++ build_id_data_len += sizeof(symtab); ++ + /* + * setup symbols string table + * 2 = 1 for 0 in 1st entry, 1 for the 0 at end of symbol for 2nd entry +@@ -376,6 +395,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_flags = 0; + shdr->sh_entsize = 0; + ++ tmp = realloc(build_id_data, build_id_data_len + symlen); ++ if (tmp == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(tmp + build_id_data_len, strsym, symlen); ++ build_id_data = tmp; ++ build_id_data_len += symlen; ++ + /* + * setup build-id section + */ +@@ -394,7 +422,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + /* + * build-id generation + */ +- sha1(code, csize, bnote.build_id); ++ sha1(build_id_data, build_id_data_len, bnote.build_id); + bnote.desc.namesz = sizeof(bnote.name); /* must include 0 termination */ + bnote.desc.descsz = sizeof(bnote.build_id); + bnote.desc.type = NT_GNU_BUILD_ID; +@@ -439,7 +467,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + (void)elf_end(e); + + free(strsym); +- ++ free(build_id_data); + + return retval; + } +-- +2.51.0 + diff --git a/queue-6.17/perf-lock-contention-load-kernel-map-before-lookup.patch b/queue-6.17/perf-lock-contention-load-kernel-map-before-lookup.patch new file mode 100644 index 0000000000..68c3ee16bb --- /dev/null +++ b/queue-6.17/perf-lock-contention-load-kernel-map-before-lookup.patch @@ -0,0 +1,56 @@ +From 31855fc65108757747c04460bdc0f03802c550f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 21:01:39 -0700 +Subject: perf lock contention: Load kernel map before lookup + +From: Namhyung Kim + +[ Upstream commit 553d18c98a896094b99a01765b9698b204183d49 ] + +On some machines, it caused troubles when it tried to find kernel +symbols. I think it's because kernel modules and kallsyms are messed +up during load and split. + +Basically we want to make sure the kernel map is loaded and the code has +it in the lock_contention_read(). But recently we added more lookups in +the lock_contention_prepare() which is called before _read(). + +Also the kernel map (kallsyms) may not be the first one in the group +like on ARM. Let's use machine__kernel_map() rather than just loading +the first map. + +Reviewed-by: Ian Rogers +Fixes: 688d2e8de231c54e ("perf lock contention: Add -l/--lock-addr option") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_lock_contention.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c +index 60b81d586323f..7b5671f13c535 100644 +--- a/tools/perf/util/bpf_lock_contention.c ++++ b/tools/perf/util/bpf_lock_contention.c +@@ -184,6 +184,9 @@ int lock_contention_prepare(struct lock_contention *con) + struct evlist *evlist = con->evlist; + struct target *target = con->target; + ++ /* make sure it loads the kernel map before lookup */ ++ map__load(machine__kernel_map(con->machine)); ++ + skel = lock_contention_bpf__open(); + if (!skel) { + pr_err("Failed to open lock-contention BPF skeleton\n"); +@@ -749,9 +752,6 @@ int lock_contention_read(struct lock_contention *con) + bpf_prog_test_run_opts(prog_fd, &opts); + } + +- /* make sure it loads the kernel map */ +- maps__load_first(machine->kmaps); +- + prev_key = NULL; + while (!bpf_map_get_next_key(fd, prev_key, &key)) { + s64 ls_key; +-- +2.51.0 + diff --git a/queue-6.17/perf-parse-events-fix-legacy-cache-events-if-event-i.patch b/queue-6.17/perf-parse-events-fix-legacy-cache-events-if-event-i.patch new file mode 100644 index 0000000000..13eb3abcea --- /dev/null +++ b/queue-6.17/perf-parse-events-fix-legacy-cache-events-if-event-i.patch @@ -0,0 +1,111 @@ +From 05034d07ac20f9bbeff0ac15f680543d232b98d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Oct 2025 11:24:04 -0700 +Subject: perf parse-events: Fix legacy cache events if event is duplicated in + a PMU + +From: Ian Rogers + +[ Upstream commit b7b76f607a15f16031001687e733046b5f6f5d86 ] + +The term list when adding an event to a PMU is expected to have the +event name for the alias lookup. Also, set found_supported so that +-EINVAL isn't returned. + +Fixes: 62593394f66a ("perf parse-events: Legacy cache names on all +PMUs and lower priority") + +Tested-by: Thomas Richter +Signed-off-by: Ian Rogers +Tested-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events.c | 28 +++++++++++++++++++++++++++- + tools/perf/util/parse-events.h | 3 ++- + tools/perf/util/parse-events.y | 2 +- + 3 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index 0026cff4d69e4..fbf287363d9e6 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -475,8 +475,10 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state, + + int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + struct parse_events_state *parse_state, +- struct parse_events_terms *parsed_terms) ++ struct parse_events_terms *parsed_terms, ++ void *loc_) + { ++ YYLTYPE *loc = loc_; + struct perf_pmu *pmu = NULL; + bool found_supported = false; + const char *config_name = get_config_name(parsed_terms); +@@ -497,12 +499,36 @@ int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + * The PMU has the event so add as not a legacy cache + * event. + */ ++ struct parse_events_terms temp_terms; ++ struct parse_events_term *term; ++ char *config = strdup(name); ++ ++ if (!config) ++ goto out_err; ++ ++ parse_events_terms__init(&temp_terms); ++ if (!parsed_terms) ++ parsed_terms = &temp_terms; ++ ++ if (parse_events_term__num(&term, ++ PARSE_EVENTS__TERM_TYPE_USER, ++ config, /*num=*/1, /*novalue=*/true, ++ loc, /*loc_val=*/NULL) < 0) { ++ zfree(&config); ++ goto out_err; ++ } ++ list_add(&term->list, &parsed_terms->terms); ++ + ret = parse_events_add_pmu(parse_state, list, pmu, + parsed_terms, + first_wildcard_match, + /*alternate_hw_config=*/PERF_COUNT_HW_MAX); ++ list_del_init(&term->list); ++ parse_events_term__delete(term); ++ parse_events_terms__exit(&temp_terms); + if (ret) + goto out_err; ++ found_supported = true; + if (first_wildcard_match == NULL) + first_wildcard_match = + container_of(list->prev, struct evsel, core.node); +diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h +index 62dc7202e3bad..c498d896badfd 100644 +--- a/tools/perf/util/parse-events.h ++++ b/tools/perf/util/parse-events.h +@@ -235,7 +235,8 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, + bool wildcard); + int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + struct parse_events_state *parse_state, +- struct parse_events_terms *parsed_terms); ++ struct parse_events_terms *parsed_terms, ++ void *loc); + int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config); + int parse_events_add_breakpoint(struct parse_events_state *parse_state, + struct list_head *list, +diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y +index a2361c0040d75..ced26c549c33a 100644 +--- a/tools/perf/util/parse-events.y ++++ b/tools/perf/util/parse-events.y +@@ -353,7 +353,7 @@ PE_LEGACY_CACHE opt_event_config + if (!list) + YYNOMEM; + +- err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2); ++ err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2, &@1); + + parse_events_terms__delete($2); + free($1); +-- +2.51.0 + diff --git a/queue-6.17/perf-record-skip-synthesize-event-when-open-evsel-fa.patch b/queue-6.17/perf-record-skip-synthesize-event-when-open-evsel-fa.patch new file mode 100644 index 0000000000..57aa62455c --- /dev/null +++ b/queue-6.17/perf-record-skip-synthesize-event-when-open-evsel-fa.patch @@ -0,0 +1,71 @@ +From acc22254a61f820a4b058bf8d1d87f1bc5d6bc62 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:50:43 +0800 +Subject: perf record: skip synthesize event when open evsel failed + +From: Shuai Xue + +[ Upstream commit 163e5f2b96632b7fb2eaa965562aca0dbdf9f996 ] + +When using perf record with the `--overwrite` option, a segmentation fault +occurs if an event fails to open. For example: + + perf record -e cycles-ct -F 1000 -a --overwrite + Error: + cycles-ct:H: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + perf: Segmentation fault + #0 0x6466b6 in dump_stack debug.c:366 + #1 0x646729 in sighandler_dump_stack debug.c:378 + #2 0x453fd1 in sigsegv_handler builtin-record.c:722 + #3 0x7f8454e65090 in __restore_rt libc-2.32.so[54090] + #4 0x6c5671 in __perf_event__synthesize_id_index synthetic-events.c:1862 + #5 0x6c5ac0 in perf_event__synthesize_id_index synthetic-events.c:1943 + #6 0x458090 in record__synthesize builtin-record.c:2075 + #7 0x45a85a in __cmd_record builtin-record.c:2888 + #8 0x45deb6 in cmd_record builtin-record.c:4374 + #9 0x4e5e33 in run_builtin perf.c:349 + #10 0x4e60bf in handle_internal_command perf.c:401 + #11 0x4e6215 in run_argv perf.c:448 + #12 0x4e653a in main perf.c:555 + #13 0x7f8454e4fa72 in __libc_start_main libc-2.32.so[3ea72] + #14 0x43a3ee in _start ??:0 + +The --overwrite option implies --tail-synthesize, which collects non-sample +events reflecting the system status when recording finishes. However, when +evsel opening fails (e.g., unsupported event 'cycles-ct'), session->evlist +is not initialized and remains NULL. The code unconditionally calls +record__synthesize() in the error path, which iterates through the NULL +evlist pointer and causes a segfault. + +To fix it, move the record__synthesize() call inside the error check block, so +it's only called when there was no error during recording, ensuring that evlist +is properly initialized. + +Fixes: 4ea648aec019 ("perf record: Add --tail-synthesize option") +Signed-off-by: Shuai Xue +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c +index 7ea3a11aca70e..e7bebd1fa810a 100644 +--- a/tools/perf/builtin-record.c ++++ b/tools/perf/builtin-record.c +@@ -2885,11 +2885,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) + rec->bytes_written += off_cpu_write(rec->session); + + record__read_lost_samples(rec); +- record__synthesize(rec, true); + /* this will be recalculated during process_buildids() */ + rec->samples = 0; + + if (!err) { ++ record__synthesize(rec, true); + if (!rec->timestamp_filename) { + record__finish_output(rec); + } else { +-- +2.51.0 + diff --git a/queue-6.17/perf-remove-get_perf_callchain-init_nr-argument.patch b/queue-6.17/perf-remove-get_perf_callchain-init_nr-argument.patch new file mode 100644 index 0000000000..26cc6eb2b9 --- /dev/null +++ b/queue-6.17/perf-remove-get_perf_callchain-init_nr-argument.patch @@ -0,0 +1,109 @@ +From db7d6670c9d060f372fcad774c60b4508eab6a7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Aug 2025 14:03:39 -0400 +Subject: perf: Remove get_perf_callchain() init_nr argument + +From: Josh Poimboeuf + +[ Upstream commit e649bcda25b5ae1a30a182cc450f928a0b282c93 ] + +The 'init_nr' argument has double duty: it's used to initialize both the +number of contexts and the number of stack entries. That's confusing +and the callers always pass zero anyway. Hard code the zero. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Namhyung Kim +Acked-by: Alexei Starovoitov +Link: https://lore.kernel.org/r/20250820180428.259565081@kernel.org +Stable-dep-of: 23f852daa4ba ("bpf: Fix stackmap overflow check in __bpf_get_stackid()") +Signed-off-by: Sasha Levin +--- + include/linux/perf_event.h | 2 +- + kernel/bpf/stackmap.c | 4 ++-- + kernel/events/callchain.c | 12 ++++++------ + kernel/events/core.c | 2 +- + 4 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h +index ec9d960256839..54e0d31afcad1 100644 +--- a/include/linux/perf_event.h ++++ b/include/linux/perf_event.h +@@ -1719,7 +1719,7 @@ DECLARE_PER_CPU(struct perf_callchain_entry, perf_callchain_entry); + extern void perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); + extern void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs); + extern struct perf_callchain_entry * +-get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, ++get_perf_callchain(struct pt_regs *regs, bool kernel, bool user, + u32 max_stack, bool crosstask, bool add_mark); + extern int get_callchain_buffers(int max_stack); + extern void put_callchain_buffers(void); +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index 3615c06b7dfa9..ec3a57a5fba1f 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -314,7 +314,7 @@ BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, + if (max_depth > sysctl_perf_event_max_stack) + max_depth = sysctl_perf_event_max_stack; + +- trace = get_perf_callchain(regs, 0, kernel, user, max_depth, ++ trace = get_perf_callchain(regs, kernel, user, max_depth, + false, false); + + if (unlikely(!trace)) +@@ -451,7 +451,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + else if (kernel && task) + trace = get_callchain_entry_for_task(task, max_depth); + else +- trace = get_perf_callchain(regs, 0, kernel, user, max_depth, ++ trace = get_perf_callchain(regs, kernel, user, max_depth, + crosstask, false); + + if (unlikely(!trace) || trace->nr < skip) { +diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c +index 2609998ca07f1..5982d18f169bd 100644 +--- a/kernel/events/callchain.c ++++ b/kernel/events/callchain.c +@@ -217,7 +217,7 @@ static void fixup_uretprobe_trampoline_entries(struct perf_callchain_entry *entr + } + + struct perf_callchain_entry * +-get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, ++get_perf_callchain(struct pt_regs *regs, bool kernel, bool user, + u32 max_stack, bool crosstask, bool add_mark) + { + struct perf_callchain_entry *entry; +@@ -232,11 +232,11 @@ get_perf_callchain(struct pt_regs *regs, u32 init_nr, bool kernel, bool user, + if (!entry) + return NULL; + +- ctx.entry = entry; +- ctx.max_stack = max_stack; +- ctx.nr = entry->nr = init_nr; +- ctx.contexts = 0; +- ctx.contexts_maxed = false; ++ ctx.entry = entry; ++ ctx.max_stack = max_stack; ++ ctx.nr = entry->nr = 0; ++ ctx.contexts = 0; ++ ctx.contexts_maxed = false; + + if (kernel && !user_mode(regs)) { + if (add_mark) +diff --git a/kernel/events/core.c b/kernel/events/core.c +index 970c4a5ab763b..01d080978865f 100644 +--- a/kernel/events/core.c ++++ b/kernel/events/core.c +@@ -8205,7 +8205,7 @@ perf_callchain(struct perf_event *event, struct pt_regs *regs) + if (!kernel && !user) + return &__empty_callchain; + +- callchain = get_perf_callchain(regs, 0, kernel, user, ++ callchain = get_perf_callchain(regs, kernel, user, + max_stack, crosstask, true); + return callchain ?: &__empty_callchain; + } +-- +2.51.0 + diff --git a/queue-6.17/perf-tools-fix-missing-feature-check-for-inherit-sam.patch b/queue-6.17/perf-tools-fix-missing-feature-check-for-inherit-sam.patch new file mode 100644 index 0000000000..503b4cde8f --- /dev/null +++ b/queue-6.17/perf-tools-fix-missing-feature-check-for-inherit-sam.patch @@ -0,0 +1,47 @@ +From c25f1ac0f2f6c7dc3a39f7d32e0b4fc58749c63d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:59:44 -0800 +Subject: perf tools: Fix missing feature check for inherit + SAMPLE_READ + +From: Namhyung Kim + +[ Upstream commit 367377f45c0b568882567f797b7b18b263505be7 ] + +It should also have PERF_SAMPLE_TID to enable inherit and PERF_SAMPLE_READ +on recent kernels. Not having _TID makes the feature check wrongly detect +the inherit and _READ support. + +It was reported that the following command failed due to the error in +the missing feature check on Intel SPR machines. + + $ perf record -e '{cpu/mem-loads-aux/S,cpu/mem-loads,ldlat=3/PS}' -- ls + Error: + Failure to open event 'cpu/mem-loads,ldlat=3/PS' on PMU 'cpu' which will be removed. + Invalid event (cpu/mem-loads,ldlat=3/PS) in per-thread mode, enable system wide with '-a'. + +Reviewed-by: Ian Rogers +Fixes: 3b193a57baf15c468 ("perf tools: Detect missing kernel features properly") +Reported-and-tested-by: Chen, Zide +Closes: https://lore.kernel.org/lkml/20251022220802.1335131-1-zide.chen@intel.com/ +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/evsel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c +index 5df59812b80ca..9efd177551f2f 100644 +--- a/tools/perf/util/evsel.c ++++ b/tools/perf/util/evsel.c +@@ -2396,7 +2396,7 @@ static bool evsel__detect_missing_features(struct evsel *evsel, struct perf_cpu + /* Please add new feature detection here. */ + + attr.inherit = true; +- attr.sample_type = PERF_SAMPLE_READ; ++ attr.sample_type = PERF_SAMPLE_READ | PERF_SAMPLE_TID; + if (has_attr_feature(&attr, /*flags=*/0)) + goto found; + perf_missing_features.inherit_sample_read = true; +-- +2.51.0 + diff --git a/queue-6.17/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-6.17/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..2adf11943a --- /dev/null +++ b/queue-6.17/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From c4fef3caedc3d0141f38a8c90b6b39080b759809 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 93c81c65b6c40..dfa8340eeaf8c 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -955,11 +955,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + map__zput(curr_map); +-- +2.51.0 + diff --git a/queue-6.17/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch b/queue-6.17/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch new file mode 100644 index 0000000000..94546c9924 --- /dev/null +++ b/queue-6.17/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch @@ -0,0 +1,41 @@ +From a4ab4e50d260d63886bd81992d377fadc86cf39b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:14 -0800 +Subject: perf tools: Mark split kallsyms DSOs as loaded + +From: Namhyung Kim + +[ Upstream commit 7da4d60db33cccd8f4c445ab20bba71531435ee5 ] + +The maps__split_kallsyms() will split symbols to module DSOs if it comes +from a module. It also handled some unusual kernel symbols after modules +by creating new kernel maps like "[kernel].0". + +But they are pseudo DSOs to have those unexpected symbols. They should +not be considered as unloaded kernel DSOs. Otherwise the dso__load() +for them will end up calling dso__load_kallsyms() and then +maps__split_kallsyms() again and again. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 3fed54de54016..93c81c65b6c40 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -967,6 +967,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + return -1; + + dso__set_kernel(ndso, dso__kernel(dso)); ++ dso__set_loaded(ndso); + + curr_map = map__new2(pos->start, ndso); + if (curr_map == NULL) { +-- +2.51.0 + diff --git a/queue-6.17/perf-x86-fix-null-event-access-and-potential-pebs-re.patch b/queue-6.17/perf-x86-fix-null-event-access-and-potential-pebs-re.patch new file mode 100644 index 0000000000..9b96c8521d --- /dev/null +++ b/queue-6.17/perf-x86-fix-null-event-access-and-potential-pebs-re.patch @@ -0,0 +1,97 @@ +From 1b896db26ac0fdcab68b48d9005ad454fbadd15b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:26 +0800 +Subject: perf/x86: Fix NULL event access and potential PEBS record loss + +From: Dapeng Mi + +[ Upstream commit 7e772a93eb61cb6265bdd1c5bde17d0f2718b452 ] + +When intel_pmu_drain_pebs_icl() is called to drain PEBS records, the +perf_event_overflow() could be called to process the last PEBS record. + +While perf_event_overflow() could trigger the interrupt throttle and +stop all events of the group, like what the below call-chain shows. + +perf_event_overflow() + -> __perf_event_overflow() + ->__perf_event_account_interrupt() + -> perf_event_throttle_group() + -> perf_event_throttle() + -> event->pmu->stop() + -> x86_pmu_stop() + +The side effect of stopping the events is that all corresponding event +pointers in cpuc->events[] array are cleared to NULL. + +Assume there are two PEBS events (event a and event b) in a group. When +intel_pmu_drain_pebs_icl() calls perf_event_overflow() to process the +last PEBS record of PEBS event a, interrupt throttle is triggered and +all pointers of event a and event b are cleared to NULL. Then +intel_pmu_drain_pebs_icl() tries to process the last PEBS record of +event b and encounters NULL pointer access. + +To avoid this issue, move cpuc->events[] clearing from x86_pmu_stop() +to x86_pmu_del(). It's safe since cpuc->active_mask or +cpuc->pebs_enabled is always checked before access the event pointer +from cpuc->events[]. + +Closes: https://lore.kernel.org/oe-lkp/202507042103.a15d2923-lkp@intel.com +Fixes: 9734e25fbf5a ("perf: Fix the throttle logic for a group") +Reported-by: kernel test robot +Suggested-by: Peter Zijlstra +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-3-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index 38f7102e2dacc..dc77e11f23657 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -1344,6 +1344,7 @@ static void x86_pmu_enable(struct pmu *pmu) + hwc->state |= PERF_HES_ARCH; + + x86_pmu_stop(event, PERF_EF_UPDATE); ++ cpuc->events[hwc->idx] = NULL; + } + + /* +@@ -1365,6 +1366,7 @@ static void x86_pmu_enable(struct pmu *pmu) + * if cpuc->enabled = 0, then no wrmsr as + * per x86_pmu_enable_event() + */ ++ cpuc->events[hwc->idx] = event; + x86_pmu_start(event, PERF_EF_RELOAD); + } + cpuc->n_added = 0; +@@ -1531,7 +1533,6 @@ static void x86_pmu_start(struct perf_event *event, int flags) + + event->hw.state = 0; + +- cpuc->events[idx] = event; + __set_bit(idx, cpuc->active_mask); + static_call(x86_pmu_enable)(event); + perf_event_update_userpage(event); +@@ -1610,7 +1611,6 @@ void x86_pmu_stop(struct perf_event *event, int flags) + if (test_bit(hwc->idx, cpuc->active_mask)) { + static_call(x86_pmu_disable)(event); + __clear_bit(hwc->idx, cpuc->active_mask); +- cpuc->events[hwc->idx] = NULL; + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + } +@@ -1648,6 +1648,7 @@ static void x86_pmu_del(struct perf_event *event, int flags) + * Not a TXN, therefore cleanup properly. + */ + x86_pmu_stop(event, PERF_EF_UPDATE); ++ cpuc->events[event->hw.idx] = NULL; + + for (i = 0; i < cpuc->n_events; i++) { + if (event == cpuc->event_list[i]) +-- +2.51.0 + diff --git a/queue-6.17/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-6.17/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..62647ce786 --- /dev/null +++ b/queue-6.17/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From 22b3edc2027e3d2dff64eb99cd344ab0512b7066 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 046d12281fd94..52270268144c2 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4029,7 +4029,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-6.17/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch b/queue-6.17/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch new file mode 100644 index 0000000000..5b5339d3f7 --- /dev/null +++ b/queue-6.17/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch @@ -0,0 +1,47 @@ +From 23b10e16f15435224789dc88a4dae0adaeb63907 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:37:52 -0700 +Subject: perf/x86/intel/cstate: Remove PC3 support from LunarLake + +From: Zhang Rui + +[ Upstream commit 4ba45f041abe60337fdeeb68553b9ee1217d544e ] + +LunarLake doesn't support Package C3. Remove the PC3 residency counter +support from LunarLake. + +Fixes: 26579860fbd5 ("perf/x86/intel/cstate: Add Lunarlake support") +Signed-off-by: Zhang Rui +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Kan Liang +Reviewed-by: Dapeng Mi +Link: https://patch.msgid.link/20251023223754.1743928-3-zide.chen@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/cstate.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index ec753e39b0077..6f5286a99e0c3 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -70,7 +70,7 @@ + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, + * GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL, +- * ADL,RPL,MTL,ARL,LNL ++ * ADL,RPL,MTL,ARL + * Scope: Package (physical package) + * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. + * perf code: 0x02 +@@ -522,7 +522,6 @@ static const struct cstate_model lnl_cstates __initconst = { + BIT(PERF_CSTATE_CORE_C7_RES), + + .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | +- BIT(PERF_CSTATE_PKG_C3_RES) | + BIT(PERF_CSTATE_PKG_C6_RES) | + BIT(PERF_CSTATE_PKG_C10_RES), + }; +-- +2.51.0 + diff --git a/queue-6.17/phy-freescale-initialize-priv-lock.patch b/queue-6.17/phy-freescale-initialize-priv-lock.patch new file mode 100644 index 0000000000..b07df19276 --- /dev/null +++ b/queue-6.17/phy-freescale-initialize-priv-lock.patch @@ -0,0 +1,71 @@ +From 4e4edd2b67923729686d9d404ca7f7273fcc1c45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 09:38:06 +0800 +Subject: phy: freescale: Initialize priv->lock + +From: Xiaolei Wang + +[ Upstream commit 95e5905698983df94069e185f9eb3c67c7cf75d5 ] + +Initialize priv->lock to fix the following warning. + +WARNING: CPU: 0 PID: 12 at kernel/locking/mutex.c:577 __mutex_lock+0x70c/0x8b8 + Modules linked in: + Hardware name: Freescale i.MX8QM MEK (DT) + Call trace: + __mutex_lock+0x70c/0x8b8 (P) + mutex_lock_nested+0x24/0x30 + imx_hsio_power_on+0x4c/0x764 + phy_power_on+0x7c/0x12c + imx_pcie_host_init+0x1d0/0x4d4 + dw_pcie_host_init+0x188/0x4b0 + imx_pcie_probe+0x324/0x6f4 + platform_probe+0x5c/0x98 + really_probe+0xbc/0x29c + __driver_probe_device+0x78/0x12c + driver_probe_device+0xd8/0x160 + __device_attach_driver+0xb8/0x138 + bus_for_each_drv+0x84/0xe4 + __device_attach_async_helper+0xb8/0xdc + async_run_entry_fn+0x34/0xe0 + process_one_work+0x220/0x694 + worker_thread+0x1c0/0x36c + kthread+0x14c/0x224 + +Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support") +Signed-off-by: Xiaolei Wang +Reviewed-by: Frank Li +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20250925013806.569658-1-xiaolei.wang@windriver.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +index 5dca93cd325c8..977d21d753a59 100644 +--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c ++++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +@@ -533,7 +533,7 @@ static struct phy *imx_hsio_xlate(struct device *dev, + + static int imx_hsio_probe(struct platform_device *pdev) + { +- int i; ++ int i, ret; + void __iomem *off; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; +@@ -545,6 +545,9 @@ static int imx_hsio_probe(struct platform_device *pdev) + return -ENOMEM; + priv->dev = &pdev->dev; + priv->drvdata = of_device_get_match_data(dev); ++ ret = devm_mutex_init(dev, &priv->lock); ++ if (ret) ++ return ret; + + /* Get HSIO configuration mode */ + if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg)) +-- +2.51.0 + diff --git a/queue-6.17/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-6.17/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..a8efd2f6cf --- /dev/null +++ b/queue-6.17/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From 7dde3fb68cbf2571e3834b0722f122d94e625528 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index ef0ef1570d392..48d43f60b8ff8 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2625,7 +2625,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2648,12 +2648,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-6.17/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch b/queue-6.17/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch new file mode 100644 index 0000000000..2f2758d475 --- /dev/null +++ b/queue-6.17/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch @@ -0,0 +1,94 @@ +From 279d384802750613e9076ea6c85f39675be1577e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 16:58:05 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Fix an error handling path in + rcar_gen3_phy_usb2_probe() + +From: Christophe JAILLET + +[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ] + +If an error occurs after the reset_control_deassert(), +reset_control_assert() must be called, as already done in the remove +function. + +Use devm_add_action_or_reset() to add the missing call and simplify the +.remove() function accordingly. + +While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. + +[claudiu.beznea: removed "struct reset_control *rstc = data;" from + rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] + +Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") +Signed-off-by: Christophe JAILLET +Reviewed-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Tested-by: Wolfram Sang +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index 47beb94cd4244..dece07c944918 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -125,7 +125,6 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; +- struct reset_control *rstc; + struct work_struct work; + spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; +@@ -699,21 +698,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static void rcar_gen3_reset_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) + { + struct device *dev = channel->dev; ++ struct reset_control *rstc; + int ret; + u32 val; + +- channel->rstc = devm_reset_control_array_get_shared(dev); +- if (IS_ERR(channel->rstc)) +- return PTR_ERR(channel->rstc); ++ rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(rstc)) ++ return PTR_ERR(rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + +- ret = reset_control_deassert(channel->rstc); ++ ret = reset_control_deassert(rstc); ++ if (ret) ++ goto rpm_put; ++ ++ ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); + if (ret) + goto rpm_put; + +@@ -860,7 +869,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + +- reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + }; + +-- +2.51.0 + diff --git a/queue-6.17/phy-rockchip-naneng-combphy-add-soc-prefix-to-regist.patch b/queue-6.17/phy-rockchip-naneng-combphy-add-soc-prefix-to-regist.patch new file mode 100644 index 0000000000..7351dbfd66 --- /dev/null +++ b/queue-6.17/phy-rockchip-naneng-combphy-add-soc-prefix-to-regist.patch @@ -0,0 +1,899 @@ +From f776132b94f1de0ef172a54bd4d2d3cef7e8f2f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Jul 2025 10:29:46 +0000 +Subject: phy: rockchip: naneng-combphy: Add SoC prefix to register definitions + +From: Yao Zi + +[ Upstream commit b3bbc6afcff50e2fd4d51dd64929e62d66fdc814 ] + +All supported variants of naneng-combphy follow a register layout +similar to the RK3568 variant with some exceptions of SoC-specific +registers. + +Add RK3568 prefix for the common set of registers and the corresponding +SoC prefix for SoC-specific registers, making usage of definitions clear +and preparing for future COMBPHY variants with a different register +layout. + +Signed-off-by: Yao Zi +Reviewed-by: Heiko Stuebner +Reviewed-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250728102947.38984-6-ziyao@disroot.org +Signed-off-by: Vinod Koul +Stable-dep-of: be866e68966d ("phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562") +Signed-off-by: Sasha Levin +--- + .../rockchip/phy-rockchip-naneng-combphy.c | 560 +++++++++--------- + 1 file changed, 288 insertions(+), 272 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index 17c6310f4b54b..ce84166cd7725 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -21,78 +21,80 @@ + #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) + + /* COMBO PHY REG */ +-#define PHYREG6 0x14 +-#define PHYREG6_PLL_DIV_MASK GENMASK(7, 6) +-#define PHYREG6_PLL_DIV_SHIFT 6 +-#define PHYREG6_PLL_DIV_2 1 +- +-#define PHYREG7 0x18 +-#define PHYREG7_TX_RTERM_MASK GENMASK(7, 4) +-#define PHYREG7_TX_RTERM_SHIFT 4 +-#define PHYREG7_TX_RTERM_50OHM 8 +-#define PHYREG7_RX_RTERM_MASK GENMASK(3, 0) +-#define PHYREG7_RX_RTERM_SHIFT 0 +-#define PHYREG7_RX_RTERM_44OHM 15 +- +-#define PHYREG8 0x1C +-#define PHYREG8_SSC_EN BIT(4) +- +-#define PHYREG10 0x24 +-#define PHYREG10_SSC_PCM_MASK GENMASK(3, 0) +-#define PHYREG10_SSC_PCM_3500PPM 7 +- +-#define PHYREG11 0x28 +-#define PHYREG11_SU_TRIM_0_7 0xF0 +- +-#define PHYREG12 0x2C +-#define PHYREG12_PLL_LPF_ADJ_VALUE 4 +- +-#define PHYREG13 0x30 +-#define PHYREG13_RESISTER_MASK GENMASK(5, 4) +-#define PHYREG13_RESISTER_SHIFT 0x4 +-#define PHYREG13_RESISTER_HIGH_Z 3 +-#define PHYREG13_CKRCV_AMP0 BIT(7) +- +-#define PHYREG14 0x34 +-#define PHYREG14_CKRCV_AMP1 BIT(0) +- +-#define PHYREG15 0x38 +-#define PHYREG15_CTLE_EN BIT(0) +-#define PHYREG15_SSC_CNT_MASK GENMASK(7, 6) +-#define PHYREG15_SSC_CNT_SHIFT 6 +-#define PHYREG15_SSC_CNT_VALUE 1 +- +-#define PHYREG16 0x3C +-#define PHYREG16_SSC_CNT_VALUE 0x5f +- +-#define PHYREG17 0x40 +- +-#define PHYREG18 0x44 +-#define PHYREG18_PLL_LOOP 0x32 +- +-#define PHYREG21 0x50 +-#define PHYREG21_RX_SQUELCH_VAL 0x0D +- +-#define PHYREG27 0x6C +-#define PHYREG27_RX_TRIM_RK3588 0x4C +- +-#define PHYREG30 0x74 +- +-#define PHYREG32 0x7C +-#define PHYREG32_SSC_MASK GENMASK(7, 4) +-#define PHYREG32_SSC_DIR_MASK GENMASK(5, 4) +-#define PHYREG32_SSC_DIR_SHIFT 4 +-#define PHYREG32_SSC_UPWARD 0 +-#define PHYREG32_SSC_DOWNWARD 1 +-#define PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) +-#define PHYREG32_SSC_OFFSET_SHIFT 6 +-#define PHYREG32_SSC_OFFSET_500PPM 1 +- +-#define PHYREG33 0x80 +-#define PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) +-#define PHYREG33_PLL_KVCO_SHIFT 2 +-#define PHYREG33_PLL_KVCO_VALUE 2 +-#define PHYREG33_PLL_KVCO_VALUE_RK3576 4 ++#define RK3568_PHYREG6 0x14 ++#define RK3568_PHYREG6_PLL_DIV_MASK GENMASK(7, 6) ++#define RK3568_PHYREG6_PLL_DIV_SHIFT 6 ++#define RK3568_PHYREG6_PLL_DIV_2 1 ++ ++#define RK3568_PHYREG7 0x18 ++#define RK3568_PHYREG7_TX_RTERM_MASK GENMASK(7, 4) ++#define RK3568_PHYREG7_TX_RTERM_SHIFT 4 ++#define RK3568_PHYREG7_TX_RTERM_50OHM 8 ++#define RK3568_PHYREG7_RX_RTERM_MASK GENMASK(3, 0) ++#define RK3568_PHYREG7_RX_RTERM_SHIFT 0 ++#define RK3568_PHYREG7_RX_RTERM_44OHM 15 ++ ++#define RK3568_PHYREG8 0x1C ++#define RK3568_PHYREG8_SSC_EN BIT(4) ++ ++#define RK3568_PHYREG11 0x28 ++#define RK3568_PHYREG11_SU_TRIM_0_7 0xF0 ++ ++#define RK3568_PHYREG12 0x2C ++#define RK3568_PHYREG12_PLL_LPF_ADJ_VALUE 4 ++ ++#define RK3568_PHYREG13 0x30 ++#define RK3568_PHYREG13_RESISTER_MASK GENMASK(5, 4) ++#define RK3568_PHYREG13_RESISTER_SHIFT 0x4 ++#define RK3568_PHYREG13_RESISTER_HIGH_Z 3 ++#define RK3568_PHYREG13_CKRCV_AMP0 BIT(7) ++ ++#define RK3568_PHYREG14 0x34 ++#define RK3568_PHYREG14_CKRCV_AMP1 BIT(0) ++ ++#define RK3568_PHYREG15 0x38 ++#define RK3568_PHYREG15_CTLE_EN BIT(0) ++#define RK3568_PHYREG15_SSC_CNT_MASK GENMASK(7, 6) ++#define RK3568_PHYREG15_SSC_CNT_SHIFT 6 ++#define RK3568_PHYREG15_SSC_CNT_VALUE 1 ++ ++#define RK3568_PHYREG16 0x3C ++#define RK3568_PHYREG16_SSC_CNT_VALUE 0x5f ++ ++#define RK3568_PHYREG18 0x44 ++#define RK3568_PHYREG18_PLL_LOOP 0x32 ++ ++#define RK3568_PHYREG32 0x7C ++#define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) ++#define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) ++#define RK3568_PHYREG32_SSC_DIR_SHIFT 4 ++#define RK3568_PHYREG32_SSC_UPWARD 0 ++#define RK3568_PHYREG32_SSC_DOWNWARD 1 ++#define RK3568_PHYREG32_SSC_OFFSET_MASK GENMASK(7, 6) ++#define RK3568_PHYREG32_SSC_OFFSET_SHIFT 6 ++#define RK3568_PHYREG32_SSC_OFFSET_500PPM 1 ++ ++#define RK3568_PHYREG33 0x80 ++#define RK3568_PHYREG33_PLL_KVCO_MASK GENMASK(4, 2) ++#define RK3568_PHYREG33_PLL_KVCO_SHIFT 2 ++#define RK3568_PHYREG33_PLL_KVCO_VALUE 2 ++#define RK3576_PHYREG33_PLL_KVCO_VALUE 4 ++ ++/* RK3588 COMBO PHY registers */ ++#define RK3588_PHYREG27 0x6C ++#define RK3588_PHYREG27_RX_TRIM 0x4C ++ ++/* RK3576 COMBO PHY registers */ ++#define RK3576_PHYREG10 0x24 ++#define RK3576_PHYREG10_SSC_PCM_MASK GENMASK(3, 0) ++#define RK3576_PHYREG10_SSC_PCM_3500PPM 7 ++ ++#define RK3576_PHYREG17 0x40 ++ ++#define RK3576_PHYREG21 0x50 ++#define RK3576_PHYREG21_RX_SQUELCH_VAL 0x0D ++ ++#define RK3576_PHYREG30 0x74 + + struct rockchip_combphy_priv; + +@@ -407,9 +409,8 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + switch (priv->type) { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, +- PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, +- PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); +@@ -418,29 +419,30 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + break; + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, +- PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, +- PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, ++ RK3568_PHYREG32); + + /* Enable adaptive CTLE for USB3.0 Rx */ +- rockchip_combphy_updatel(priv, PHYREG15_CTLE_EN, +- PHYREG15_CTLE_EN, PHYREG15); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG15_CTLE_EN, ++ RK3568_PHYREG15_CTLE_EN, RK3568_PHYREG15); + + /* Set PLL KVCO fine tuning signals */ +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ BIT(3), RK3568_PHYREG33); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + + /* Set PLL input clock divider 1/2 */ +- val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); ++ val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); + + /* Set PLL loop divider */ +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); +@@ -458,11 +460,12 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_24MHz: + if (priv->type == PHY_TYPE_USB3) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ +- val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); +- rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, +- val, PHYREG15); ++ val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, ++ RK3568_PHYREG15_SSC_CNT_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, ++ val, RK3568_PHYREG15); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + } + break; + case REF_CLOCK_25MHz: +@@ -472,19 +475,20 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO tuning fine */ +- val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE); +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, ++ RK3568_PHYREG33_PLL_KVCO_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Enable controlling random jitter, aka RMJ */ +- writel(0x4, priv->mmio + PHYREG12); ++ writel(0x4, priv->mmio + RK3568_PHYREG12); + +- val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, +- val, PHYREG6); ++ val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, ++ val, RK3568_PHYREG6); + +- writel(0x32, priv->mmio + PHYREG18); +- writel(0xf0, priv->mmio + PHYREG11); ++ writel(0x32, priv->mmio + RK3568_PHYREG18); ++ writel(0xf0, priv->mmio + RK3568_PHYREG11); + } + break; + default: +@@ -495,20 +499,21 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + if (priv->ext_refclk) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { +- val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; +- val |= PHYREG13_CKRCV_AMP0; +- rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); +- +- val = readl(priv->mmio + PHYREG14); +- val |= PHYREG14_CKRCV_AMP1; +- writel(val, priv->mmio + PHYREG14); ++ val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; ++ val |= RK3568_PHYREG13_CKRCV_AMP0; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, ++ RK3568_PHYREG13); ++ ++ val = readl(priv->mmio + RK3568_PHYREG14); ++ val |= RK3568_PHYREG14_CKRCV_AMP1; ++ writel(val, priv->mmio + RK3568_PHYREG14); + } + } + + if (priv->enable_ssc) { +- val = readl(priv->mmio + PHYREG8); +- val |= PHYREG8_SSC_EN; +- writel(val, priv->mmio + PHYREG8); ++ val = readl(priv->mmio + RK3568_PHYREG8); ++ val |= RK3568_PHYREG8_SSC_EN; ++ writel(val, priv->mmio + RK3568_PHYREG8); + } + + return 0; +@@ -555,9 +560,9 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + switch (priv->type) { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum. */ +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, +- PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, +- PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); +@@ -567,30 +572,28 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum. */ +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, +- PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, +- PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT, ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + /* Enable adaptive CTLE for USB3.0 Rx. */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + + /* Set PLL KVCO fine tuning signals. */ +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, +- PHYREG33); ++ val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); + + /* Enable controlling random jitter. */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + + /* Set PLL input clock divider 1/2. */ +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, +- PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, +- PHYREG6); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, ++ RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, ++ RK3568_PHYREG6); + +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_sel_usb, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); +@@ -608,16 +611,16 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx. */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + /* + * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. + * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) + */ +- val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; +- val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; +- writel(val, priv->mmio + PHYREG7); ++ val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; ++ val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; ++ writel(val, priv->mmio + RK3568_PHYREG7); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); +@@ -652,11 +655,11 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_24MHz: + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ +- val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, +- val, PHYREG15); ++ val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, ++ val, RK3568_PHYREG15); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + } + break; + +@@ -668,24 +671,26 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO fine tuning. */ +- val = PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Enable controlling random jitter. */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + +- val = PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, +- val, PHYREG6); ++ val = RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, ++ val, RK3568_PHYREG6); + +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + } else if (priv->type == PHY_TYPE_SATA) { + /* downward spread spectrum +500ppm */ +- val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; +- val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << ++ RK3568_PHYREG32_SSC_OFFSET_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, ++ RK3568_PHYREG32); + } + break; + +@@ -697,20 +702,21 @@ static int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + if (priv->ext_refclk) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { +- val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; +- val |= PHYREG13_CKRCV_AMP0; +- rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); +- +- val = readl(priv->mmio + PHYREG14); +- val |= PHYREG14_CKRCV_AMP1; +- writel(val, priv->mmio + PHYREG14); ++ val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; ++ val |= RK3568_PHYREG13_CKRCV_AMP0; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, ++ RK3568_PHYREG13); ++ ++ val = readl(priv->mmio + RK3568_PHYREG14); ++ val |= RK3568_PHYREG14_CKRCV_AMP1; ++ writel(val, priv->mmio + RK3568_PHYREG14); + } + } + + if (priv->enable_ssc) { +- val = readl(priv->mmio + PHYREG8); +- val |= PHYREG8_SSC_EN; +- writel(val, priv->mmio + PHYREG8); ++ val = readl(priv->mmio + RK3568_PHYREG8); ++ val |= RK3568_PHYREG8_SSC_EN; ++ writel(val, priv->mmio + RK3568_PHYREG8); + } + + return 0; +@@ -771,8 +777,8 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + switch (priv->type) { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ +- val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); +@@ -782,32 +788,33 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ +- val = FIELD_PREP(PHYREG32_SSC_MASK, PHYREG32_SSC_DOWNWARD); +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ val = FIELD_PREP(RK3568_PHYREG32_SSC_MASK, RK3568_PHYREG32_SSC_DOWNWARD); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + /* Enable adaptive CTLE for USB3.0 Rx */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + + /* Set PLL KVCO fine tuning signals */ +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, BIT(3), PHYREG33); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, BIT(3), ++ RK3568_PHYREG33); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + + /* Set PLL input clock divider 1/2 */ +- val = FIELD_PREP(PHYREG6_PLL_DIV_MASK, PHYREG6_PLL_DIV_2); +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, val, PHYREG6); ++ val = FIELD_PREP(RK3568_PHYREG6_PLL_DIV_MASK, RK3568_PHYREG6_PLL_DIV_2); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, val, RK3568_PHYREG6); + + /* Set PLL loop divider */ +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + + /* Set Rx squelch input filler bandwidth */ +- writel(PHYREG21_RX_SQUELCH_VAL, priv->mmio + PHYREG21); ++ writel(RK3576_PHYREG21_RX_SQUELCH_VAL, priv->mmio + RK3576_PHYREG21); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); +@@ -816,14 +823,14 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + + /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ +- val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; +- val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; +- writel(val, priv->mmio + PHYREG7); ++ val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; ++ val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; ++ writel(val, priv->mmio + RK3568_PHYREG7); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); +@@ -845,19 +852,21 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ +- val = FIELD_PREP(PHYREG15_SSC_CNT_MASK, PHYREG15_SSC_CNT_VALUE); +- rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, +- val, PHYREG15); ++ val = FIELD_PREP(RK3568_PHYREG15_SSC_CNT_MASK, ++ RK3568_PHYREG15_SSC_CNT_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, ++ val, RK3568_PHYREG15); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + } else if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO tuning fine */ +- val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, ++ RK3576_PHYREG33_PLL_KVCO_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Set up rx_pck invert and rx msb to disable */ +- writel(0x00, priv->mmio + PHYREG27); ++ writel(0x00, priv->mmio + RK3588_PHYREG27); + + /* + * Set up SU adjust signal: +@@ -865,11 +874,11 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + * su_trim[15:8], PLL LPF R1 adujst bits[9:7]=3'b011 + * su_trim[31:24], CKDRV adjust + */ +- writel(0x90, priv->mmio + PHYREG11); +- writel(0x02, priv->mmio + PHYREG12); +- writel(0x57, priv->mmio + PHYREG14); ++ writel(0x90, priv->mmio + RK3568_PHYREG11); ++ writel(0x02, priv->mmio + RK3568_PHYREG12); ++ writel(0x57, priv->mmio + RK3568_PHYREG14); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + } + break; + +@@ -881,15 +890,16 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* gate_tx_pck_sel length select work for L1SS */ +- writel(0xc0, priv->mmio + PHYREG30); ++ writel(0xc0, priv->mmio + RK3576_PHYREG30); + + /* PLL KVCO tuning fine */ +- val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, ++ RK3576_PHYREG33_PLL_KVCO_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ +- writel(0x4c, priv->mmio + PHYREG27); ++ writel(0x4c, priv->mmio + RK3588_PHYREG27); + + /* + * Set up SU adjust signal: +@@ -899,20 +909,23 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + * su_trim[23:16], CKRCV adjust + * su_trim[31:24], CKDRV adjust + */ +- writel(0x90, priv->mmio + PHYREG11); +- writel(0x43, priv->mmio + PHYREG12); +- writel(0x88, priv->mmio + PHYREG13); +- writel(0x56, priv->mmio + PHYREG14); ++ writel(0x90, priv->mmio + RK3568_PHYREG11); ++ writel(0x43, priv->mmio + RK3568_PHYREG12); ++ writel(0x88, priv->mmio + RK3568_PHYREG13); ++ writel(0x56, priv->mmio + RK3568_PHYREG14); + } else if (priv->type == PHY_TYPE_SATA) { + /* downward spread spectrum +500ppm */ +- val = FIELD_PREP(PHYREG32_SSC_DIR_MASK, PHYREG32_SSC_DOWNWARD); +- val |= FIELD_PREP(PHYREG32_SSC_OFFSET_MASK, PHYREG32_SSC_OFFSET_500PPM); +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ val = FIELD_PREP(RK3568_PHYREG32_SSC_DIR_MASK, ++ RK3568_PHYREG32_SSC_DOWNWARD); ++ val |= FIELD_PREP(RK3568_PHYREG32_SSC_OFFSET_MASK, ++ RK3568_PHYREG32_SSC_OFFSET_500PPM); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, ++ RK3568_PHYREG32); + + /* ssc ppm adjust to 3500ppm */ +- rockchip_combphy_updatel(priv, PHYREG10_SSC_PCM_MASK, +- PHYREG10_SSC_PCM_3500PPM, +- PHYREG10); ++ rockchip_combphy_updatel(priv, RK3576_PHYREG10_SSC_PCM_MASK, ++ RK3576_PHYREG10_SSC_PCM_3500PPM, ++ RK3576_PHYREG10); + } + break; + +@@ -924,12 +937,13 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + if (priv->ext_refclk) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { +- val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, ++ RK3576_PHYREG33_PLL_KVCO_VALUE); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Set up rx_trim: PLL LPF C1 85pf R1 2.5kohm */ +- writel(0x0c, priv->mmio + PHYREG27); ++ writel(0x0c, priv->mmio + RK3588_PHYREG27); + + /* + * Set up SU adjust signal: +@@ -939,25 +953,25 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + * su_trim[23:16], CKRCV adjust + * su_trim[31:24], CKDRV adjust + */ +- writel(0x90, priv->mmio + PHYREG11); +- writel(0x43, priv->mmio + PHYREG12); +- writel(0x88, priv->mmio + PHYREG13); +- writel(0x56, priv->mmio + PHYREG14); ++ writel(0x90, priv->mmio + RK3568_PHYREG11); ++ writel(0x43, priv->mmio + RK3568_PHYREG12); ++ writel(0x88, priv->mmio + RK3568_PHYREG13); ++ writel(0x56, priv->mmio + RK3568_PHYREG14); + } + } + + if (priv->enable_ssc) { +- val = readl(priv->mmio + PHYREG8); +- val |= PHYREG8_SSC_EN; +- writel(val, priv->mmio + PHYREG8); ++ val = readl(priv->mmio + RK3568_PHYREG8); ++ val |= RK3568_PHYREG8_SSC_EN; ++ writel(val, priv->mmio + RK3568_PHYREG8); + + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_24MHz) { + /* Set PLL loop divider */ +- writel(0x00, priv->mmio + PHYREG17); +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); ++ writel(0x00, priv->mmio + RK3576_PHYREG17); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); + + /* Set up rx_pck invert and rx msb to disable */ +- writel(0x00, priv->mmio + PHYREG27); ++ writel(0x00, priv->mmio + RK3588_PHYREG27); + + /* + * Set up SU adjust signal: +@@ -966,16 +980,17 @@ static int rk3576_combphy_cfg(struct rockchip_combphy_priv *priv) + * su_trim[23:16], CKRCV adjust + * su_trim[31:24], CKDRV adjust + */ +- writel(0x90, priv->mmio + PHYREG11); +- writel(0x02, priv->mmio + PHYREG12); +- writel(0x08, priv->mmio + PHYREG13); +- writel(0x57, priv->mmio + PHYREG14); +- writel(0x40, priv->mmio + PHYREG15); ++ writel(0x90, priv->mmio + RK3568_PHYREG11); ++ writel(0x02, priv->mmio + RK3568_PHYREG12); ++ writel(0x08, priv->mmio + RK3568_PHYREG13); ++ writel(0x57, priv->mmio + RK3568_PHYREG14); ++ writel(0x40, priv->mmio + RK3568_PHYREG15); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + +- val = FIELD_PREP(PHYREG33_PLL_KVCO_MASK, PHYREG33_PLL_KVCO_VALUE_RK3576); +- writel(val, priv->mmio + PHYREG33); ++ val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, ++ RK3576_PHYREG33_PLL_KVCO_VALUE); ++ writel(val, priv->mmio + RK3568_PHYREG33); + } + } + +@@ -1045,30 +1060,28 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) + break; + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, +- PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT, +- PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, RK3568_PHYREG32); + + /* Enable adaptive CTLE for USB3.0 Rx. */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + + /* Set PLL KVCO fine tuning signals. */ +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- PHYREG33_PLL_KVCO_VALUE << PHYREG33_PLL_KVCO_SHIFT, +- PHYREG33); ++ val = RK3568_PHYREG33_PLL_KVCO_VALUE << RK3568_PHYREG33_PLL_KVCO_SHIFT, ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, val, RK3568_PHYREG33); + + /* Enable controlling random jitter. */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + + /* Set PLL input clock divider 1/2. */ +- rockchip_combphy_updatel(priv, PHYREG6_PLL_DIV_MASK, +- PHYREG6_PLL_DIV_2 << PHYREG6_PLL_DIV_SHIFT, +- PHYREG6); ++ rockchip_combphy_updatel(priv, RK3568_PHYREG6_PLL_DIV_MASK, ++ RK3568_PHYREG6_PLL_DIV_2 << RK3568_PHYREG6_PLL_DIV_SHIFT, ++ RK3568_PHYREG6); + +- writel(PHYREG18_PLL_LOOP, priv->mmio + PHYREG18); +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG18_PLL_LOOP, priv->mmio + RK3568_PHYREG18); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); +@@ -1076,16 +1089,16 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) + break; + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx. */ +- val = readl(priv->mmio + PHYREG15); +- val |= PHYREG15_CTLE_EN; +- writel(val, priv->mmio + PHYREG15); ++ val = readl(priv->mmio + RK3568_PHYREG15); ++ val |= RK3568_PHYREG15_CTLE_EN; ++ writel(val, priv->mmio + RK3568_PHYREG15); + /* + * Set tx_rterm=50ohm and rx_rterm=44ohm for SATA. + * 0: 60ohm, 8: 50ohm 15: 44ohm (by step abort 1ohm) + */ +- val = PHYREG7_TX_RTERM_50OHM << PHYREG7_TX_RTERM_SHIFT; +- val |= PHYREG7_RX_RTERM_44OHM << PHYREG7_RX_RTERM_SHIFT; +- writel(val, priv->mmio + PHYREG7); ++ val = RK3568_PHYREG7_TX_RTERM_50OHM << RK3568_PHYREG7_TX_RTERM_SHIFT; ++ val |= RK3568_PHYREG7_RX_RTERM_44OHM << RK3568_PHYREG7_RX_RTERM_SHIFT; ++ writel(val, priv->mmio + RK3568_PHYREG7); + + rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_sata, true); + rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_sata, true); +@@ -1107,11 +1120,11 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_24MHz: + if (priv->type == PHY_TYPE_USB3 || priv->type == PHY_TYPE_SATA) { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz. */ +- val = PHYREG15_SSC_CNT_VALUE << PHYREG15_SSC_CNT_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG15_SSC_CNT_MASK, +- val, PHYREG15); ++ val = RK3568_PHYREG15_SSC_CNT_VALUE << RK3568_PHYREG15_SSC_CNT_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG15_SSC_CNT_MASK, ++ val, RK3568_PHYREG15); + +- writel(PHYREG16_SSC_CNT_VALUE, priv->mmio + PHYREG16); ++ writel(RK3568_PHYREG16_SSC_CNT_VALUE, priv->mmio + RK3568_PHYREG16); + } + break; + +@@ -1122,23 +1135,25 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { + /* PLL KVCO fine tuning. */ +- val = 4 << PHYREG33_PLL_KVCO_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG33_PLL_KVCO_MASK, +- val, PHYREG33); ++ val = 4 << RK3568_PHYREG33_PLL_KVCO_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG33_PLL_KVCO_MASK, ++ val, RK3568_PHYREG33); + + /* Enable controlling random jitter. */ +- writel(PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + PHYREG12); ++ writel(RK3568_PHYREG12_PLL_LPF_ADJ_VALUE, priv->mmio + RK3568_PHYREG12); + + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ +- writel(PHYREG27_RX_TRIM_RK3588, priv->mmio + PHYREG27); ++ writel(RK3588_PHYREG27_RX_TRIM, priv->mmio + RK3588_PHYREG27); + + /* Set up su_trim: */ +- writel(PHYREG11_SU_TRIM_0_7, priv->mmio + PHYREG11); ++ writel(RK3568_PHYREG11_SU_TRIM_0_7, priv->mmio + RK3568_PHYREG11); + } else if (priv->type == PHY_TYPE_SATA) { + /* downward spread spectrum +500ppm */ +- val = PHYREG32_SSC_DOWNWARD << PHYREG32_SSC_DIR_SHIFT; +- val |= PHYREG32_SSC_OFFSET_500PPM << PHYREG32_SSC_OFFSET_SHIFT; +- rockchip_combphy_updatel(priv, PHYREG32_SSC_MASK, val, PHYREG32); ++ val = RK3568_PHYREG32_SSC_DOWNWARD << RK3568_PHYREG32_SSC_DIR_SHIFT; ++ val |= RK3568_PHYREG32_SSC_OFFSET_500PPM << ++ RK3568_PHYREG32_SSC_OFFSET_SHIFT; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG32_SSC_MASK, val, ++ RK3568_PHYREG32); + } + break; + default: +@@ -1149,20 +1164,21 @@ static int rk3588_combphy_cfg(struct rockchip_combphy_priv *priv) + if (priv->ext_refclk) { + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_ext, true); + if (priv->type == PHY_TYPE_PCIE && rate == REF_CLOCK_100MHz) { +- val = PHYREG13_RESISTER_HIGH_Z << PHYREG13_RESISTER_SHIFT; +- val |= PHYREG13_CKRCV_AMP0; +- rockchip_combphy_updatel(priv, PHYREG13_RESISTER_MASK, val, PHYREG13); +- +- val = readl(priv->mmio + PHYREG14); +- val |= PHYREG14_CKRCV_AMP1; +- writel(val, priv->mmio + PHYREG14); ++ val = RK3568_PHYREG13_RESISTER_HIGH_Z << RK3568_PHYREG13_RESISTER_SHIFT; ++ val |= RK3568_PHYREG13_CKRCV_AMP0; ++ rockchip_combphy_updatel(priv, RK3568_PHYREG13_RESISTER_MASK, val, ++ RK3568_PHYREG13); ++ ++ val = readl(priv->mmio + RK3568_PHYREG14); ++ val |= RK3568_PHYREG14_CKRCV_AMP1; ++ writel(val, priv->mmio + RK3568_PHYREG14); + } + } + + if (priv->enable_ssc) { +- val = readl(priv->mmio + PHYREG8); +- val |= PHYREG8_SSC_EN; +- writel(val, priv->mmio + PHYREG8); ++ val = readl(priv->mmio + RK3568_PHYREG8); ++ val |= RK3568_PHYREG8_SSC_EN; ++ writel(val, priv->mmio + RK3568_PHYREG8); + } + + return 0; +-- +2.51.0 + diff --git a/queue-6.17/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch b/queue-6.17/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch new file mode 100644 index 0000000000..ed51b1338b --- /dev/null +++ b/queue-6.17/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch @@ -0,0 +1,53 @@ +From fd4181c83792d26d527042d1c115cafb2c916a2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 17:52:06 +0800 +Subject: phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562 + +From: Shawn Lin + +[ Upstream commit be866e68966d20bcc4a73708093d577176f99c0c ] + +When PCIe link enters L1 PM substates, the PHY will turn off its +PLL for power-saving. However, it turns off the PLL too fast which +leads the PHY to be broken. According to the PHY document, we need +to delay PLL turnoff time. + +Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562") +Signed-off-by: Shawn Lin +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/1763459526-35004-2-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index ce84166cd7725..6d69288693952 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -64,6 +64,10 @@ + #define RK3568_PHYREG18 0x44 + #define RK3568_PHYREG18_PLL_LOOP 0x32 + ++#define RK3568_PHYREG30 0x74 ++#define RK3568_PHYREG30_GATE_TX_PCK_SEL BIT(7) ++#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7) ++ + #define RK3568_PHYREG32 0x7C + #define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) + #define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) +@@ -474,6 +478,10 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { ++ /* Gate_tx_pck_sel length select for L1ss support */ ++ rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL, ++ RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF, ++ RK3568_PHYREG30); + /* PLL KVCO tuning fine */ + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3568_PHYREG33_PLL_KVCO_VALUE); +-- +2.51.0 + diff --git a/queue-6.17/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch b/queue-6.17/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch new file mode 100644 index 0000000000..54050620a3 --- /dev/null +++ b/queue-6.17/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch @@ -0,0 +1,78 @@ +From 7b5ea549dc3df8bcc8c3a9c0ad4f34bb8d01ed0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:54 +0200 +Subject: phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc + mode + +From: Cristian Ciocaltea + +[ Upstream commit 72126e9623e1696ea83c77ef6d0306a6263bdd6b ] + +When making use of the clock provider functionality, the output clock +does normally match the TMDS character rate, which is what the PHY PLL +gets configured to. + +However, this is only applicable for default color depth of 8 bpc. For +higher depths, the output clock is further divided by the hardware +according to the formula: + + output_clock_rate = tmds_char_rate * 8 / bpc + +Since the existence of the clock divider wasn't taken into account when +support for high bpc has been introduced, make the necessary adjustments +to report the correct clock rate. + +Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth management") +Reported-by: Andy Yan +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-1-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 79db57ee90d14..8adf6e84fc0b7 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -1038,7 +1038,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) + + ret = rk_hdptx_post_enable_pll(hdptx); + if (!ret) +- hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate; ++ hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, ++ hdptx->hdmi_cfg.bpc); + + return ret; + } +@@ -1896,19 +1897,20 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, + * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with + * a different rate argument. + */ +- return hdptx->hdmi_cfg.tmds_char_rate; ++ return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc); + } + + static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { + struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); ++ unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); + + /* Revert any unlikely TMDS char rate change since round_rate() */ +- if (hdptx->hdmi_cfg.tmds_char_rate != rate) { +- dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n", +- rate, hdptx->hdmi_cfg.tmds_char_rate); +- hdptx->hdmi_cfg.tmds_char_rate = rate; ++ if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { ++ dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n", ++ tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); ++ hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; + } + + /* +-- +2.51.0 + diff --git a/queue-6.17/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch b/queue-6.17/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch new file mode 100644 index 0000000000..324a3e8b8d --- /dev/null +++ b/queue-6.17/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch @@ -0,0 +1,59 @@ +From 1541638a9832f0a3f0e35425f624e1a8ce28ccfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:56 +0200 +Subject: phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding + the limits + +From: Cristian Ciocaltea + +[ Upstream commit 51023cf6cc5db3423dea6620746d9087e336e024 ] + +Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of +other lanes. It's worth noting this might only happen when dealing with +HDMI 2.0 rates. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-3-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 9751f7ad00f4f..5605610465bc8 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { + + static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0312), 0x00), +- REG_SEQ0(LANE_REG(031e), 0x00), + REG_SEQ0(LANE_REG(0412), 0x00), +- REG_SEQ0(LANE_REG(041e), 0x00), + REG_SEQ0(LANE_REG(0512), 0x00), +- REG_SEQ0(LANE_REG(051e), 0x00), + REG_SEQ0(LANE_REG(0612), 0x00), +- REG_SEQ0(LANE_REG(061e), 0x08), + REG_SEQ0(LANE_REG(0303), 0x2f), + REG_SEQ0(LANE_REG(0403), 0x2f), + REG_SEQ0(LANE_REG(0503), 0x2f), +@@ -687,6 +683,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0406), 0x1c), + REG_SEQ0(LANE_REG(0506), 0x1c), + REG_SEQ0(LANE_REG(0606), 0x1c), ++ /* Keep Inter-Pair Skew in the limits */ ++ REG_SEQ0(LANE_REG(031e), 0x02), ++ REG_SEQ0(LANE_REG(041e), 0x02), ++ REG_SEQ0(LANE_REG(051e), 0x02), ++ REG_SEQ0(LANE_REG(061e), 0x0a), + }; + + static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = { +-- +2.51.0 + diff --git a/queue-6.17/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch b/queue-6.17/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch new file mode 100644 index 0000000000..e623f81383 --- /dev/null +++ b/queue-6.17/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch @@ -0,0 +1,53 @@ +From 7b668dabf15cfbe70d627cccebdfb7f83ef83ef9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:55 +0200 +Subject: phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth + +From: Cristian Ciocaltea + +[ Upstream commit 8daaced9f5eeb4a2c8ca08b0a8286b6a498a8387 ] + +Due to its relatively low frequency, a noise stemming from the 24MHz PLL +reference clock may traverse the low-pass loop filter of ROPLL, which +could potentially generate some HDMI flash artifacts. + +Reduce ROPLL loop bandwidth in an attempt to mitigate the problem. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-2-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 8adf6e84fc0b7..9751f7ad00f4f 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0043), 0x00), + REG_SEQ0(CMN_REG(0044), 0x46), + REG_SEQ0(CMN_REG(0045), 0x24), +- REG_SEQ0(CMN_REG(0046), 0xff), + REG_SEQ0(CMN_REG(0047), 0x00), +- REG_SEQ0(CMN_REG(0048), 0x44), + REG_SEQ0(CMN_REG(0049), 0xfa), + REG_SEQ0(CMN_REG(004a), 0x08), + REG_SEQ0(CMN_REG(004b), 0x00), +@@ -575,6 +573,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0034), 0x00), + REG_SEQ0(CMN_REG(003d), 0x40), + REG_SEQ0(CMN_REG(0042), 0x78), ++ REG_SEQ0(CMN_REG(0046), 0xdd), ++ REG_SEQ0(CMN_REG(0048), 0x11), + REG_SEQ0(CMN_REG(004e), 0x34), + REG_SEQ0(CMN_REG(005c), 0x25), + REG_SEQ0(CMN_REG(005e), 0x4f), +-- +2.51.0 + diff --git a/queue-6.17/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch b/queue-6.17/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch new file mode 100644 index 0000000000..d10e02e874 --- /dev/null +++ b/queue-6.17/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch @@ -0,0 +1,37 @@ +From 7ac788ac88022bccd9c14c00d9847649bc0f0558 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 09:45:49 +0100 +Subject: pidfs: add missing BUILD_BUG_ON() assert on struct pidfd_info + +From: Christian Brauner + +[ Upstream commit d8fc51d8fa3b9894713e7eebcf574bee488fa3e1 ] + +Validate that the size of struct pidfd_info is correctly updated. + +Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-4-ca449b7b7aa0@kernel.org +Fixes: 1d8db6fd698d ("pidfs, coredump: add PIDFD_INFO_COREDUMP") +Reviewed-by: Alexander Mikhalitsyn +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/pidfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/pidfs.c b/fs/pidfs.c +index 2c9c7636253af..3fde97d2889ba 100644 +--- a/fs/pidfs.c ++++ b/fs/pidfs.c +@@ -306,6 +306,8 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) + const struct cred *c; + __u64 mask; + ++ BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER1); ++ + if (!uinfo) + return -EINVAL; + if (usize < PIDFD_INFO_SIZE_VER0) +-- +2.51.0 + diff --git a/queue-6.17/pidfs-add-missing-pidfd_info_size_ver1.patch b/queue-6.17/pidfs-add-missing-pidfd_info_size_ver1.patch new file mode 100644 index 0000000000..041fa9103c --- /dev/null +++ b/queue-6.17/pidfs-add-missing-pidfd_info_size_ver1.patch @@ -0,0 +1,36 @@ +From be8aa3c640154637f1159ca560ac270b66a6db17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 09:45:48 +0100 +Subject: pidfs: add missing PIDFD_INFO_SIZE_VER1 + +From: Christian Brauner + +[ Upstream commit 4061c43a99772c66c378cfacaa71550ab3b35909 ] + +We grew struct pidfd_info not too long ago. + +Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-3-ca449b7b7aa0@kernel.org +Fixes: 1d8db6fd698d ("pidfs, coredump: add PIDFD_INFO_COREDUMP") +Reviewed-by: Alexander Mikhalitsyn +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + include/uapi/linux/pidfd.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h +index 957db425d459a..6ccbabd9a68d8 100644 +--- a/include/uapi/linux/pidfd.h ++++ b/include/uapi/linux/pidfd.h +@@ -28,6 +28,7 @@ + #define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */ + + #define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */ ++#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */ + + /* + * Values for @coredump_mask in pidfd_info. +-- +2.51.0 + diff --git a/queue-6.17/pinctrl-renesas-rzg2l-fix-pmc-restore.patch b/queue-6.17/pinctrl-renesas-rzg2l-fix-pmc-restore.patch new file mode 100644 index 0000000000..9910444ac2 --- /dev/null +++ b/queue-6.17/pinctrl-renesas-rzg2l-fix-pmc-restore.patch @@ -0,0 +1,41 @@ +From 0c790f6f587d963f0e9656684d3f3a38b1b14a72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 12:15:52 +0100 +Subject: pinctrl: renesas: rzg2l: Fix PMC restore + +From: Biju Das + +[ Upstream commit cea950101108b7bfffe26ec4007b8e263a4b56a8 ] + +PMC restore needs unlocking the register using the PWPR register. + +Fixes: ede014cd1ea6422d ("pinctrl: renesas: rzg2l: Add function pointer for PMC register write") +Signed-off-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250921111557.103069-2-biju.das.jz@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +index 289917a0e8725..9330d1bcf6b24 100644 +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -3008,7 +3008,11 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen + * Now cache the registers or set them in the order suggested by + * HW manual (section "Operation for GPIO Function"). + */ +- RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ if (suspend) ++ RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ else ++ pctrl->data->pmc_writeb(pctrl, cache->pmc[port], PMC(off)); ++ + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off), + cache->iolh[0][port]); +-- +2.51.0 + diff --git a/queue-6.17/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-6.17/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..a091cbd62c --- /dev/null +++ b/queue-6.17/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From 1d8590bf258bc18e2f8011f970f2b879807ef69c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 8aedee2720bcb..ac5eae50b8a2b 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -485,7 +485,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -549,9 +550,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-6.17/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.17/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..8192fc2a21 --- /dev/null +++ b/queue-6.17/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From 303f8c5ee1f68b51feb507b650ebd72a8f8e64a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 823c8fe758e2c..d9a2d20a7e6b2 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1671,7 +1671,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-6.17/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch b/queue-6.17/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch new file mode 100644 index 0000000000..5dbec66c18 --- /dev/null +++ b/queue-6.17/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch @@ -0,0 +1,43 @@ +From b6b63c2a0f297a479ef0249e62f9fc4d6eaf7474 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Sep 2025 14:21:35 +0800 +Subject: PM / devfreq: hisi: Fix potential UAF in OPP handling + +From: Pengjie Zhang + +[ Upstream commit 26dd44a40096468396b6438985d8e44e0743f64c ] + +Ensure all required data is acquired before calling dev_pm_opp_put(opp) +to maintain correct resource acquisition and release order. + +Fixes: 7da2fdaaa1e6 ("PM / devfreq: Add HiSilicon uncore frequency scaling driver") +Signed-off-by: Pengjie Zhang +Reviewed-by: Jie Zhan +Acked-by: Chanwoo Choi +Signed-off-by: Chanwoo Choi +Link: https://patchwork.kernel.org/project/linux-pm/patch/20250915062135.748653-1-zhangpengjie2@huawei.com/ +Signed-off-by: Sasha Levin +--- + drivers/devfreq/hisi_uncore_freq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/devfreq/hisi_uncore_freq.c b/drivers/devfreq/hisi_uncore_freq.c +index 96d1815059e32..c1ed70fa0a400 100644 +--- a/drivers/devfreq/hisi_uncore_freq.c ++++ b/drivers/devfreq/hisi_uncore_freq.c +@@ -265,10 +265,11 @@ static int hisi_uncore_target(struct device *dev, unsigned long *freq, + dev_err(dev, "Failed to get opp for freq %lu hz\n", *freq); + return PTR_ERR(opp); + } +- dev_pm_opp_put(opp); + + data = (u32)(dev_pm_opp_get_freq(opp) / HZ_PER_MHZ); + ++ dev_pm_opp_put(opp); ++ + return hisi_uncore_cmd_send(uncore, HUCF_PCC_CMD_SET_FREQ, &data); + } + +-- +2.51.0 + diff --git a/queue-6.17/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-6.17/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..dcf8bc1d3b --- /dev/null +++ b/queue-6.17/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From 40283986d7561fa88b38e4bb2ddf7d58764c1d5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9236e00785786..9933cdc5c387a 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -364,7 +364,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-6.17/power-supply-cw2015-check-devm_delayed_work_autocanc.patch b/queue-6.17/power-supply-cw2015-check-devm_delayed_work_autocanc.patch new file mode 100644 index 0000000000..436bea8fbb --- /dev/null +++ b/queue-6.17/power-supply-cw2015-check-devm_delayed_work_autocanc.patch @@ -0,0 +1,46 @@ +From 6792fd12de71c3308b5a6f93f301b15014ad4b2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:07:11 +0300 +Subject: power: supply: cw2015: Check devm_delayed_work_autocancel() return + code + +From: Ivan Abramov + +[ Upstream commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 ] + +Since devm_delayed_work_autocancel() may fail, add return code check and +exit cw_bat_probe() on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/cw2015_battery.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 382dff8805c62..f41ce7e41fac9 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -702,7 +702,13 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ if (ret) { ++ dev_err_probe(&client->dev, ret, ++ "Failed to register delayed work\n"); ++ return ret; ++ } ++ + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +-- +2.51.0 + diff --git a/queue-6.17/power-supply-max17040-check-iio_read_channel_process.patch b/queue-6.17/power-supply-max17040-check-iio_read_channel_process.patch new file mode 100644 index 0000000000..7581e94daf --- /dev/null +++ b/queue-6.17/power-supply-max17040-check-iio_read_channel_process.patch @@ -0,0 +1,50 @@ +From bb9353ccb6014d121bd458c1fa0fd676550a2d02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:36:47 +0300 +Subject: power: supply: max17040: Check iio_read_channel_processed() return + code + +From: Ivan Abramov + +[ Upstream commit 2c68ac48c52ad146523f32b01d70009622bf81aa ] + +Since iio_read_channel_processed() may fail, return its exit code on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 814755c48f8b ("power: max17040: get thermal data from adc if available") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008133648.559286-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/max17040_battery.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c +index c1640bc6accd2..48453508688a4 100644 +--- a/drivers/power/supply/max17040_battery.c ++++ b/drivers/power/supply/max17040_battery.c +@@ -388,6 +388,7 @@ static int max17040_get_property(struct power_supply *psy, + union power_supply_propval *val) + { + struct max17040_chip *chip = power_supply_get_drvdata(psy); ++ int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +@@ -410,7 +411,10 @@ static int max17040_get_property(struct power_supply *psy, + if (!chip->channel_temp) + return -ENODATA; + +- iio_read_channel_processed(chip->channel_temp, &val->intval); ++ ret = iio_read_channel_processed(chip->channel_temp, &val->intval); ++ if (ret) ++ return ret; ++ + val->intval /= 100; /* Convert from milli- to deci-degree */ + + break; +-- +2.51.0 + diff --git a/queue-6.17/power-supply-rt5033_charger-fix-device-node-referenc.patch b/queue-6.17/power-supply-rt5033_charger-fix-device-node-referenc.patch new file mode 100644 index 0000000000..c1247551a2 --- /dev/null +++ b/queue-6.17/power-supply-rt5033_charger-fix-device-node-referenc.patch @@ -0,0 +1,41 @@ +From 216a9c87a8bd85a99c2750edbcea9cc7d37f6ba5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 19:32:34 +0800 +Subject: power: supply: rt5033_charger: Fix device node reference leaks + +From: Haotian Zhang + +[ Upstream commit 6cdc4d488c2f3a61174bfba4e8cc4ac92c219258 ] + +The device node pointers `np_conn` and `np_edev`, obtained from +of_parse_phandle() and of_get_parent() respectively, are not released. +This results in a reference count leak. + +Add of_node_put() calls after the last use of these device nodes to +properly release their references and fix the leaks. + +Fixes: 8242336dc8a8 ("power: supply: rt5033_charger: Add cable detection and USB OTG supply") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20250929113234.1726-1-vulab@iscas.ac.cn +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt5033_charger.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/power/supply/rt5033_charger.c b/drivers/power/supply/rt5033_charger.c +index 2fdc584397075..de724f23e453b 100644 +--- a/drivers/power/supply/rt5033_charger.c ++++ b/drivers/power/supply/rt5033_charger.c +@@ -701,6 +701,8 @@ static int rt5033_charger_probe(struct platform_device *pdev) + np_conn = of_parse_phandle(pdev->dev.of_node, "richtek,usb-connector", 0); + np_edev = of_get_parent(np_conn); + charger->edev = extcon_find_edev_by_node(np_edev); ++ of_node_put(np_edev); ++ of_node_put(np_conn); + if (IS_ERR(charger->edev)) { + dev_warn(charger->dev, "no extcon device found in device-tree\n"); + goto out; +-- +2.51.0 + diff --git a/queue-6.17/power-supply-rt9467-prevent-using-uninitialized-loca.patch b/queue-6.17/power-supply-rt9467-prevent-using-uninitialized-loca.patch new file mode 100644 index 0000000000..3d639fd7e5 --- /dev/null +++ b/queue-6.17/power-supply-rt9467-prevent-using-uninitialized-loca.patch @@ -0,0 +1,40 @@ +From 82d58b334d5a16ca03f98b957d4c9d66f7a2954b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:53:08 +0300 +Subject: power: supply: rt9467: Prevent using uninitialized local variable in + rt9467_set_value_from_ranges() + +From: Murad Masimov + +[ Upstream commit 15aca30cc6c69806054b896a2ccf7577239cb878 ] + +There is a typo in rt9467_set_value_from_ranges() that can cause leaving local +variable sel with an undefined value which is then used in regmap_field_write(). + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Murad Masimov +Link: https://patch.msgid.link/20251009145308.1830893-1-m.masimov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index 5f3efcac4a1bb..3beb8a763a923 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -376,7 +376,7 @@ static int rt9467_set_value_from_ranges(struct rt9467_chg_data *data, + if (rsel == RT9467_RANGE_VMIVR) { + ret = linear_range_get_selector_high(range, value, &sel, &found); + if (ret) +- value = range->max_sel; ++ sel = range->max_sel; + } else { + linear_range_get_selector_within(range, value, &sel); + } +-- +2.51.0 + diff --git a/queue-6.17/power-supply-rt9467-return-error-on-failure-in-rt946.patch b/queue-6.17/power-supply-rt9467-return-error-on-failure-in-rt946.patch new file mode 100644 index 0000000000..1b0f010be5 --- /dev/null +++ b/queue-6.17/power-supply-rt9467-return-error-on-failure-in-rt946.patch @@ -0,0 +1,44 @@ +From 02b560f1b024935fd9c9f41b5dc78c339141da05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:47:24 +0300 +Subject: power: supply: rt9467: Return error on failure in + rt9467_set_value_from_ranges() + +From: Ivan Abramov + +[ Upstream commit 8b27fe2d8d2380118c343629175385ff587e2fe4 ] + +The return value of rt9467_set_value_from_ranges() when setting AICL VTH is +not checked, even though it may fail. + +Log error and return from rt9467_run_aicl() on fail. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009144725.562278-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index e9aba9ad393c9..5f3efcac4a1bb 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -588,6 +588,10 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) + aicl_vth = mivr_vth + RT9467_AICLVTH_GAP_uV; + ret = rt9467_set_value_from_ranges(data, F_AICL_VTH, + RT9467_RANGE_AICL_VTH, aicl_vth); ++ if (ret) { ++ dev_err(data->dev, "Failed to set AICL VTH\n"); ++ return ret; ++ } + + /* Trigger AICL function */ + ret = regmap_field_write(data->rm_field[F_AICL_MEAS], 1); +-- +2.51.0 + diff --git a/queue-6.17/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-6.17/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..d7cb5edbc7 --- /dev/null +++ b/queue-6.17/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From 0e046e9a63a2b303b8fe218932d29b4e1e72c527 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 6acdba7885ca5..78fa0573ef25c 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.17/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-6.17/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..41bf703b15 --- /dev/null +++ b/queue-6.17/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From 78364ae294698fd13e198ec60ddfb6595308a7a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index f4a8c98772491..1beb578c64114 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -263,10 +263,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -306,10 +305,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-6.17/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch b/queue-6.17/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch new file mode 100644 index 0000000000..36fb392dcb --- /dev/null +++ b/queue-6.17/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch @@ -0,0 +1,78 @@ +From 1a014ac5dab3cd5cb362f1346f9cc95f833591d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:27 +0530 +Subject: powerpc/64s/hash: Restrict stress_hpt_struct memblock region to + within RMA limit + +From: Ritesh Harjani (IBM) + +[ Upstream commit 17b45ccf09882e0c808ad2cf62acdc90ad968746 ] + +When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real +Addressing Mode during early boot. During this, we should ensure that +memory region allocations for stress_hpt_struct should happen from +within RMA region as otherwise the boot might get stuck while doing +memset of this region. + +History behind why do we have RMA region limitation is better explained +in these 2 patches [1] & [2]. This patch ensures that memset to +stress_hpt_struct during early boot does not cross ppc64_rma_size +boundary. + +[1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/ +[2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/ + +Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/hash_utils.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c +index 4693c464fc5af..1e062056cfb82 100644 +--- a/arch/powerpc/mm/book3s64/hash_utils.c ++++ b/arch/powerpc/mm/book3s64/hash_utils.c +@@ -1302,11 +1302,14 @@ static void __init htab_initialize(void) + unsigned long table; + unsigned long pteg_count; + unsigned long prot; +- phys_addr_t base = 0, size = 0, end; ++ phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; + u64 i; + + DBG(" -> htab_initialize()\n"); + ++ if (firmware_has_feature(FW_FEATURE_LPAR)) ++ limit = ppc64_rma_size; ++ + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { + mmu_kernel_ssize = MMU_SEGSIZE_1T; + mmu_highuser_ssize = MMU_SEGSIZE_1T; +@@ -1322,7 +1325,7 @@ static void __init htab_initialize(void) + // Too early to use nr_cpu_ids, so use NR_CPUS + tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, + __alignof__(struct stress_hpt_struct), +- 0, MEMBLOCK_ALLOC_ANYWHERE); ++ MEMBLOCK_LOW_LIMIT, limit); + memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); + stress_hpt_struct = __va(tmp); + +@@ -1356,11 +1359,10 @@ static void __init htab_initialize(void) + mmu_hash_ops.hpte_clear_all(); + #endif + } else { +- unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; + + table = memblock_phys_alloc_range(htab_size_bytes, + htab_size_bytes, +- 0, limit); ++ MEMBLOCK_LOW_LIMIT, limit); + if (!table) + panic("ERROR: Failed to allocate %pa bytes below %pa\n", + &htab_size_bytes, &limit); +-- +2.51.0 + diff --git a/queue-6.17/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-6.17/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..87fa86af6c --- /dev/null +++ b/queue-6.17/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From 5c9740cfdd4de8b1fffcb42213b67575968432ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index a6baa6166d940..671d0dc00c6d0 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-6.17/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch b/queue-6.17/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch new file mode 100644 index 0000000000..a5459e1675 --- /dev/null +++ b/queue-6.17/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch @@ -0,0 +1,83 @@ +From cde4e720e7c8c6adc686efc3e05c35f4cad9b9ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 09:09:41 +0530 +Subject: powerpc/kdump: Fix size calculation for hot-removed memory ranges + +From: Sourabh Jain + +[ Upstream commit 7afe2383eff05f76f4ce2cfda658b7889c89f101 ] + +The elfcorehdr segment in the kdump image stores information about the +memory regions (called crash memory ranges) that the kdump kernel must +capture. + +When a memory hot-remove event occurs, the kernel regenerates the +elfcorehdr for the currently loaded kdump image to remove the +hot-removed memory from the crash memory ranges. + +Call chain: +remove_mem_range() +update_crash_elfcorehdr() +arch_crash_handle_hotplug_event() +crash_handle_hotplug_event() + +While removing the hot-removed memory from the crash memory ranges in +remove_mem_range(), if the removed memory lies within an existing crash +range, that range is split into two. During this split, the size of the +second range was being calculated incorrectly. + +This leads to dump capture failure with makedumpfile with below error: + +$ makedumpfile -l -d 31 /proc/vmcore /tmp/vmcore + +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:16 +validate_mem_section: Can't read mem_section array. +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:8 +get_mm_sparsemem: Can't get the address of mem_section. + +The updated crash memory range in PT_LOAD entry is holding incorrect +data (checkout FileSiz and MemSiz): + +readelf -a /proc/vmcore + + Type Offset VirtAddr PhysAddr + FileSiz MemSiz Flags Align + LOAD 0x0000000b013d0000 0xc000000b80000000 0x0000000b80000000 + 0xffffffffc0000000 0xffffffffc0000000 RWE 0x0 + + +Update the size calculation for the new crash memory range to fix this +issue. + +Note: This problem will not occur if the kdump kernel is loaded or +reloaded after a memory hot-remove operation. + +Fixes: 849599b702ef ("powerpc/crash: add crash memory hotplug support") +Reported-by: Shirisha G +Signed-off-by: Sourabh Jain +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20251105033941.1752287-1-sourabhjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kexec/ranges.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c +index 3702b0bdab141..426bdca4667e7 100644 +--- a/arch/powerpc/kexec/ranges.c ++++ b/arch/powerpc/kexec/ranges.c +@@ -697,8 +697,8 @@ int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size) + * two half. + */ + else { ++ size = mem_rngs->ranges[i].end - end + 1; + mem_rngs->ranges[i].end = base - 1; +- size = mem_rngs->ranges[i].end - end; + ret = add_mem_range(mem_ranges, end + 1, size); + } + } +-- +2.51.0 + diff --git a/queue-6.17/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-6.17/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..1cf8f15fab --- /dev/null +++ b/queue-6.17/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From d0d33f2d356c9a4432bef76ff7c377809a88b184 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index dc9e4a14b8854..8892f218a8147 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-6.17/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-6.17/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..bf8b1e337f --- /dev/null +++ b/queue-6.17/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From a94566bd36ca3201aa6c569965065c6fa76b4511 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 578e95e0296c6..532903da521fd 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -34,29 +34,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return pwmchip_get_drvdata(chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -102,6 +79,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -119,8 +99,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + }; + +-- +2.51.0 + diff --git a/queue-6.17/random-use-offstack-cpumask-when-necessary.patch b/queue-6.17/random-use-offstack-cpumask-when-necessary.patch new file mode 100644 index 0000000000..6d6571d4cc --- /dev/null +++ b/queue-6.17/random-use-offstack-cpumask-when-necessary.patch @@ -0,0 +1,94 @@ +From 194f266df05dd6fd943963d7e32f9b9849abb22a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 11:27:08 +0200 +Subject: random: use offstack cpumask when necessary + +From: Arnd Bergmann + +[ Upstream commit 5d49f1a5bd358d24e5f88b23b46da833de1dbec8 ] + +The entropy generation function keeps a local cpu mask on the stack, +which can trigger warnings in configurations with a large number of +CPUs: + + drivers/char/random.c:1292:20: error: stack frame size (1288) + exceeds limit (1280) in 'try_to_generate_entropy' [-Werror,-Wframe-larger-than] + +Use the cpumask interface to dynamically allocate it in those +configurations. + +Fixes: 1c21fe00eda7 ("random: spread out jitter callback to different CPUs") +Signed-off-by: Arnd Bergmann +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Sasha Levin +--- + drivers/char/random.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index b8b24b6ed3fe4..4ba5f0c4c8b24 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1296,6 +1296,7 @@ static void __cold try_to_generate_entropy(void) + struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES); + unsigned int i, num_different = 0; + unsigned long last = random_get_entropy(); ++ cpumask_var_t timer_cpus; + int cpu = -1; + + for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) { +@@ -1310,13 +1311,15 @@ static void __cold try_to_generate_entropy(void) + + atomic_set(&stack->samples, 0); + timer_setup_on_stack(&stack->timer, entropy_timer, 0); ++ if (!alloc_cpumask_var(&timer_cpus, GFP_KERNEL)) ++ goto out; ++ + while (!crng_ready() && !signal_pending(current)) { + /* + * Check !timer_pending() and then ensure that any previous callback has finished + * executing by checking timer_delete_sync_try(), before queueing the next one. + */ + if (!timer_pending(&stack->timer) && timer_delete_sync_try(&stack->timer) >= 0) { +- struct cpumask timer_cpus; + unsigned int num_cpus; + + /* +@@ -1326,19 +1329,19 @@ static void __cold try_to_generate_entropy(void) + preempt_disable(); + + /* Only schedule callbacks on timer CPUs that are online. */ +- cpumask_and(&timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); +- num_cpus = cpumask_weight(&timer_cpus); ++ cpumask_and(timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); ++ num_cpus = cpumask_weight(timer_cpus); + /* In very bizarre case of misconfiguration, fallback to all online. */ + if (unlikely(num_cpus == 0)) { +- timer_cpus = *cpu_online_mask; +- num_cpus = cpumask_weight(&timer_cpus); ++ *timer_cpus = *cpu_online_mask; ++ num_cpus = cpumask_weight(timer_cpus); + } + + /* Basic CPU round-robin, which avoids the current CPU. */ + do { +- cpu = cpumask_next(cpu, &timer_cpus); ++ cpu = cpumask_next(cpu, timer_cpus); + if (cpu >= nr_cpu_ids) +- cpu = cpumask_first(&timer_cpus); ++ cpu = cpumask_first(timer_cpus); + } while (cpu == smp_processor_id() && num_cpus > 1); + + /* Expiring the timer at `jiffies` means it's the next tick. */ +@@ -1354,6 +1357,8 @@ static void __cold try_to_generate_entropy(void) + } + mix_pool_bytes(&stack->entropy, sizeof(stack->entropy)); + ++ free_cpumask_var(timer_cpus); ++out: + timer_delete_sync(&stack->timer); + timer_destroy_on_stack(&stack->timer); + } +-- +2.51.0 + diff --git a/queue-6.17/ras-report-all-arm-processor-cper-information-to-use.patch b/queue-6.17/ras-report-all-arm-processor-cper-information-to-use.patch new file mode 100644 index 0000000000..35b55fcc21 --- /dev/null +++ b/queue-6.17/ras-report-all-arm-processor-cper-information-to-use.patch @@ -0,0 +1,308 @@ +From 3da655cd778d3149c94667c88bcec4abc03bbbae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 09:52:52 -0700 +Subject: RAS: Report all ARM processor CPER information to userspace + +From: Jason Tian + +[ Upstream commit 05954511b73e748d0370549ad9dd9cd95297d97a ] + +The ARM processor CPER record was added in UEFI v2.6 and remained +unchanged up to v2.10. + +Yet, the original arm_event trace code added by + + e9279e83ad1f ("trace, ras: add ARM processor error trace event") + +is incomplete, as it only traces some fields of UAPI 2.6 table N.16, not +exporting any information from tables N.17 to N.29 of the record. + +This is not enough for the user to be able to figure out what has +exactly happened or to take appropriate action. + +According to the UEFI v2.9 specification chapter N2.4.4, the ARM +processor error section includes: + +- several (ERR_INFO_NUM) ARM processor error information structures + (Tables N.17 to N.20); +- several (CONTEXT_INFO_NUM) ARM processor context information + structures (Tables N.21 to N.29); +- several vendor specific error information structures. The + size is given by Section Length minus the size of the other + fields. + +In addition, it also exports two fields that are parsed by the GHES +driver when firmware reports it, e.g.: + +- error severity +- CPU logical index + +Report all of these information to userspace via a the ARM tracepoint so +that userspace can properly record the error and take decisions related +to CPU core isolation according to error severity and other info. + +The updated ARM trace event now contains the following fields: + +====================================== ============================= +UEFI field on table N.16 ARM Processor trace fields +====================================== ============================= +Validation handled when filling data for + affinity MPIDR and running + state. +ERR_INFO_NUM pei_len +CONTEXT_INFO_NUM ctx_len +Section Length indirectly reported by + pei_len, ctx_len and oem_len +Error affinity level affinity +MPIDR_EL1 mpidr +MIDR_EL1 midr +Running State running_state +PSCI State psci_state +Processor Error Information Structure pei_err - count at pei_len +Processor Context ctx_err- count at ctx_len +Vendor Specific Error Info oem - count at oem_len +====================================== ============================= + +It should be noted that decoding of tables N.17 to N.29, if needed, will +be handled in userspace. That gives more flexibility, as there won't be +any need to flood the kernel with micro-architecture specific error +decoding. + +Also, decoding the other fields require a complex logic, and should be +done for each of the several values inside the record field. So, let +userspace daemons like rasdaemon decode them, parsing such tables and +having vendor-specific micro-architecture-specific decoders. + + [mchehab: modified description, solved merge conflicts and fixed coding style] + +Signed-off-by: Jason Tian +Co-developed-by: Shengwei Luo +Signed-off-by: Shengwei Luo +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Daniel Ferguson # rebased +Reviewed-by: Jonathan Cameron +Tested-by: Shiju Jose +Acked-by: Borislav Petkov (AMD) +Fixes: e9279e83ad1f ("trace, ras: add ARM processor error trace event") +Link: https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#arm-processor-error-section +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/acpi/apei/ghes.c | 11 ++++----- + drivers/ras/ras.c | 40 ++++++++++++++++++++++++++++++-- + include/linux/ras.h | 16 ++++++++++--- + include/ras/ras_event.h | 49 ++++++++++++++++++++++++++++++++++++---- + 4 files changed, 99 insertions(+), 17 deletions(-) + +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index a0d54993edb3b..7fca0ede9ecc0 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -552,7 +552,7 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + } + + static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, +- int sev, bool sync) ++ int sev, bool sync) + { + struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); + int flags = sync ? MF_ACTION_REQUIRED : 0; +@@ -560,9 +560,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, + int sec_sev, i; + char *p; + +- log_arm_hw_error(err); +- + sec_sev = ghes_severity(gdata->error_severity); ++ log_arm_hw_error(err, sec_sev); + if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) + return false; + +@@ -895,11 +894,9 @@ static void ghes_do_proc(struct ghes *ghes, + + arch_apei_report_mem_error(sev, mem_err); + queued = ghes_handle_memory_failure(gdata, sev, sync); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { + ghes_handle_aer(gdata); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { + queued = ghes_handle_arm_hw_error(gdata, sev, sync); + } else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) { + struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata); +diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c +index a6e4792a1b2e9..c1b36a5601c4b 100644 +--- a/drivers/ras/ras.c ++++ b/drivers/ras/ras.c +@@ -52,9 +52,45 @@ void log_non_standard_event(const guid_t *sec_type, const guid_t *fru_id, + trace_non_standard_event(sec_type, fru_id, fru_text, sev, err, len); + } + +-void log_arm_hw_error(struct cper_sec_proc_arm *err) ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) + { +- trace_arm_event(err); ++ struct cper_arm_err_info *err_info; ++ struct cper_arm_ctx_info *ctx_info; ++ u8 *ven_err_data; ++ u32 ctx_len = 0; ++ int n, sz, cpu; ++ s32 vsei_len; ++ u32 pei_len; ++ u8 *pei_err, *ctx_err; ++ ++ pei_len = sizeof(struct cper_arm_err_info) * err->err_info_num; ++ pei_err = (u8 *)(err + 1); ++ ++ err_info = (struct cper_arm_err_info *)(err + 1); ++ ctx_info = (struct cper_arm_ctx_info *)(err_info + err->err_info_num); ++ ctx_err = (u8 *)ctx_info; ++ ++ for (n = 0; n < err->context_info_num; n++) { ++ sz = sizeof(struct cper_arm_ctx_info) + ctx_info->size; ++ ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + sz); ++ ctx_len += sz; ++ } ++ ++ vsei_len = err->section_length - (sizeof(struct cper_sec_proc_arm) + pei_len + ctx_len); ++ if (vsei_len < 0) { ++ pr_warn(FW_BUG "section length: %d\n", err->section_length); ++ pr_warn(FW_BUG "section length is too small\n"); ++ pr_warn(FW_BUG "firmware-generated error record is incorrect\n"); ++ vsei_len = 0; ++ } ++ ven_err_data = (u8 *)ctx_info; ++ ++ cpu = GET_LOGICAL_INDEX(err->mpidr); ++ if (cpu < 0) ++ cpu = -1; ++ ++ trace_arm_event(err, pei_err, pei_len, ctx_err, ctx_len, ++ ven_err_data, (u32)vsei_len, sev, cpu); + } + + static int __init ras_init(void) +diff --git a/include/linux/ras.h b/include/linux/ras.h +index a64182bc72ad3..468941bfe855f 100644 +--- a/include/linux/ras.h ++++ b/include/linux/ras.h +@@ -24,8 +24,7 @@ int __init parse_cec_param(char *str); + void log_non_standard_event(const guid_t *sec_type, + const guid_t *fru_id, const char *fru_text, + const u8 sev, const u8 *err, const u32 len); +-void log_arm_hw_error(struct cper_sec_proc_arm *err); +- ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev); + #else + static inline void + log_non_standard_event(const guid_t *sec_type, +@@ -33,7 +32,7 @@ log_non_standard_event(const guid_t *sec_type, + const u8 sev, const u8 *err, const u32 len) + { return; } + static inline void +-log_arm_hw_error(struct cper_sec_proc_arm *err) { return; } ++log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; } + #endif + + struct atl_err { +@@ -53,4 +52,15 @@ static inline unsigned long + amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; } + #endif /* CONFIG_AMD_ATL */ + ++#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) ++#include ++/* ++ * Include ARM-specific SMP header which provides a function mapping mpidr to ++ * CPU logical index. ++ */ ++#define GET_LOGICAL_INDEX(mpidr) get_logical_index(mpidr & MPIDR_HWID_BITMASK) ++#else ++#define GET_LOGICAL_INDEX(mpidr) -EINVAL ++#endif /* CONFIG_ARM || CONFIG_ARM64 */ ++ + #endif /* __RAS_H__ */ +diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h +index c8cd0f00c8454..c9f0b1018bcce 100644 +--- a/include/ras/ras_event.h ++++ b/include/ras/ras_event.h +@@ -168,11 +168,25 @@ TRACE_EVENT(mc_event, + * This event is generated when hardware detects an ARM processor error + * has occurred. UEFI 2.6 spec section N.2.4.4. + */ ++#define APEIL "ARM Processor Err Info data len" ++#define APEID "ARM Processor Err Info raw data" ++#define APECIL "ARM Processor Err Context Info data len" ++#define APECID "ARM Processor Err Context Info raw data" ++#define VSEIL "Vendor Specific Err Info data len" ++#define VSEID "Vendor Specific Err Info raw data" + TRACE_EVENT(arm_event, + +- TP_PROTO(const struct cper_sec_proc_arm *proc), ++ TP_PROTO(const struct cper_sec_proc_arm *proc, ++ const u8 *pei_err, ++ const u32 pei_len, ++ const u8 *ctx_err, ++ const u32 ctx_len, ++ const u8 *oem, ++ const u32 oem_len, ++ u8 sev, ++ int cpu), + +- TP_ARGS(proc), ++ TP_ARGS(proc, pei_err, pei_len, ctx_err, ctx_len, oem, oem_len, sev, cpu), + + TP_STRUCT__entry( + __field(u64, mpidr) +@@ -180,6 +194,14 @@ TRACE_EVENT(arm_event, + __field(u32, running_state) + __field(u32, psci_state) + __field(u8, affinity) ++ __field(u32, pei_len) ++ __dynamic_array(u8, pei_buf, pei_len) ++ __field(u32, ctx_len) ++ __dynamic_array(u8, ctx_buf, ctx_len) ++ __field(u32, oem_len) ++ __dynamic_array(u8, oem_buf, oem_len) ++ __field(u8, sev) ++ __field(int, cpu) + ), + + TP_fast_assign( +@@ -199,12 +221,29 @@ TRACE_EVENT(arm_event, + __entry->running_state = ~0; + __entry->psci_state = ~0; + } ++ __entry->pei_len = pei_len; ++ memcpy(__get_dynamic_array(pei_buf), pei_err, pei_len); ++ __entry->ctx_len = ctx_len; ++ memcpy(__get_dynamic_array(ctx_buf), ctx_err, ctx_len); ++ __entry->oem_len = oem_len; ++ memcpy(__get_dynamic_array(oem_buf), oem, oem_len); ++ __entry->sev = sev; ++ __entry->cpu = cpu; + ), + +- TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " +- "running state: %d; PSCI state: %d", ++ TP_printk("cpu: %d; error: %d; affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " ++ "running state: %d; PSCI state: %d; " ++ "%s: %d; %s: %s; %s: %d; %s: %s; %s: %d; %s: %s", ++ __entry->cpu, ++ __entry->sev, + __entry->affinity, __entry->mpidr, __entry->midr, +- __entry->running_state, __entry->psci_state) ++ __entry->running_state, __entry->psci_state, ++ APEIL, __entry->pei_len, APEID, ++ __print_hex(__get_dynamic_array(pei_buf), __entry->pei_len), ++ APECIL, __entry->ctx_len, APECID, ++ __print_hex(__get_dynamic_array(ctx_buf), __entry->ctx_len), ++ VSEIL, __entry->oem_len, VSEID, ++ __print_hex(__get_dynamic_array(oem_buf), __entry->oem_len)) + ); + + /* +-- +2.51.0 + diff --git a/queue-6.17/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-6.17/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..c4781fcc57 --- /dev/null +++ b/queue-6.17/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From 2726ed794a2350b3c9149092366562df49e8feb9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index 89186c499dd47..c26cb83ca0711 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-6.17/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch b/queue-6.17/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch new file mode 100644 index 0000000000..0c5f583211 --- /dev/null +++ b/queue-6.17/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch @@ -0,0 +1,40 @@ +From 07de0f46d546230a50a2e89496ba3cb4583ba643 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:54 -0800 +Subject: RDMA/bnxt_re: Fix the inline size for GenP7 devices + +From: Selvin Xavier + +[ Upstream commit 6afe40ff484a1155b71158b911c65299496e35c3 ] + +Inline size supported by the device is based on the number +of SGEs supported by the adapter. Change the inline +size calculation based on that. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kashyap Desai +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 68981399598d8..f40b7d1692b06 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -161,7 +161,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw) + attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1; + attr->max_srq_sges = sb->max_srq_sge; + attr->max_pkey = 1; +- attr->max_inline_data = le32_to_cpu(sb->max_inline_data); ++ attr->max_inline_data = attr->max_qp_sges * sizeof(struct sq_sge); + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) + attr->l2_db_size = (sb->l2_db_space_size + 1) * + (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); +-- +2.51.0 + diff --git a/queue-6.17/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch b/queue-6.17/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch new file mode 100644 index 0000000000..181f403d8a --- /dev/null +++ b/queue-6.17/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch @@ -0,0 +1,109 @@ +From 6057bc5ee649fa742268f3fd0f76099361f3198f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:55 -0800 +Subject: RDMA/bnxt_re: Pass correct flag for dma mr creation + +From: Selvin Xavier + +[ Upstream commit a26c4c7cdb50247b8486f1caa1ea8ab5e5c37edf ] + +DMA MR doesn't use the unified MR model. So the lkey passed +on to the reg_mr command to FW should contain the correct +lkey. Driver is incorrectly over writing the lkey with pdid +and firmware commands fails due to this. + +Avoid passing the wrong key for cases where the unified MR +registration is not used. + +Fixes: f786eebbbefa ("RDMA/bnxt_re: Avoid an extra hwrm per MR creation") +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-2-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 +++++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 6 +++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.h | 2 +- + 3 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 12fee23de81e7..ba87606263cfb 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -599,7 +599,8 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd) + mr->qplib_mr.va = (u64)(unsigned long)fence->va; + mr->qplib_mr.total_size = BNXT_RE_FENCE_BYTES; + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, +- BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE); ++ BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register fence-MR\n"); + goto fail; +@@ -3972,7 +3973,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *ib_pd, int mr_access_flags) + mr->qplib_mr.hwq.level = PBL_LVL_MAX; + mr->qplib_mr.total_size = -1; /* Infinte length */ + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, 0, +- PAGE_SIZE); ++ PAGE_SIZE, false); + if (rc) + goto fail_mr; + +@@ -4202,7 +4203,8 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64 + + umem_pgs = ib_umem_num_dma_blocks(umem, page_size); + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, umem, +- umem_pgs, page_size); ++ umem_pgs, page_size, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register user MR - rc = %d\n", rc); + rc = -EIO; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index f40b7d1692b06..6d1d55c8423d0 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -615,7 +615,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + } + + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size) ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; + struct bnxt_qplib_hwq_attr hwq_attr = {}; +@@ -677,7 +677,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + req.access = (mr->access_flags & BNXT_QPLIB_MR_ACCESS_MASK); + req.va = cpu_to_le64(mr->va); + req.key = cpu_to_le32(mr->lkey); +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) ++ if (unified_mr) + req.key = cpu_to_le32(mr->pd->id); + req.flags = cpu_to_le16(mr->flags); + req.mr_size = cpu_to_le64(mr->total_size); +@@ -688,7 +688,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + if (rc) + goto fail; + +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) { ++ if (unified_mr) { + mr->lkey = le32_to_cpu(resp.xid); + mr->rkey = mr->lkey; + } +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +index 09faf4a1e849c..4e080108b1f24 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +@@ -340,7 +340,7 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, + int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + bool block); + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size); ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr); + int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr); + int bnxt_qplib_alloc_fast_reg_mr(struct bnxt_qplib_res *res, + struct bnxt_qplib_mrw *mr, int max); +-- +2.51.0 + diff --git a/queue-6.17/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch b/queue-6.17/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch new file mode 100644 index 0000000000..00db18324a --- /dev/null +++ b/queue-6.17/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch @@ -0,0 +1,166 @@ +From db6bdb56910fd7899feec6487c48a10bab6c9c4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:47 -0600 +Subject: RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY + +From: Jacob Moroni + +[ Upstream commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f ] + +The HW disables bounds checking for MRs with a length of zero, so +the driver will only allow a zero length MR if the "all_memory" +flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY +is set for the PD. + +This means that the "get_dma_mr" method will currently fail unless +the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue +because the "get_dma_mr" method is only ever invoked if the device +does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY +is set, and so far, all IRDMA HW supports the local DMA lkey. + +However, some new HW does not support the local DMA lkey, so the +"get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY +being set. + +To support HW that does not allow the local DMA lkey, the logic has +been changed to pass an explicit flag to indicate when a dma_mr is +being created so that the zero length will be allowed. + +Also, the "all_memory" flag has been forced to false for normal MR +allocation since these MRs are never supposed to provide global +unsafe rkey semantics anyway; only the MR created with "get_dma_mr" +should support this. + +Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/cm.c | 2 +- + drivers/infiniband/hw/irdma/main.h | 2 +- + drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- + drivers/infiniband/hw/irdma/verbs.h | 3 ++- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c +index c6a0a661d6e7e..f4f4f92ba63ac 100644 +--- a/drivers/infiniband/hw/irdma/cm.c ++++ b/drivers/infiniband/hw/irdma/cm.c +@@ -3710,7 +3710,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + iwpd = iwqp->iwpd; + tagged_offset = (uintptr_t)iwqp->ietf_mem.va; + ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, +- IB_ACCESS_LOCAL_WRITE, &tagged_offset); ++ IB_ACCESS_LOCAL_WRITE, &tagged_offset, false); + if (IS_ERR(ibmr)) { + ret = -ENOMEM; + goto error; +diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h +index 674acc9521681..f863c0aaf85d7 100644 +--- a/drivers/infiniband/hw/irdma/main.h ++++ b/drivers/infiniband/hw/irdma/main.h +@@ -538,7 +538,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src); + u16 irdma_get_vlan_ipv4(u32 *addr); + void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac); + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size, +- int acc, u64 *iova_start); ++ int acc, u64 *iova_start, bool dma_mr); + int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw); + void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq); + int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index eb4683b248af9..f8a7a0382a38a 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2654,7 +2654,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; + info->pd_id = iwpd->sc_pd.pd_id; + info->total_len = iwmr->len; +- info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; + info->remote_access = true; + cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; + cqp_info->post_sq = 1; +@@ -2665,7 +2664,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + if (status) + return status; + +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + return 0; + } + +@@ -2806,7 +2805,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + stag_info->total_len = iwmr->len; + stag_info->access_rights = irdma_get_mr_access(access); + stag_info->pd_id = iwpd->sc_pd.pd_id; +- stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; ++ stag_info->all_memory = iwmr->dma_mr; + if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) + stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; + else +@@ -2833,7 +2832,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + + if (!ret) +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + + return ret; + } +@@ -3169,7 +3168,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr) + if (status) + return status; + +- iwmr->is_hwreg = 0; ++ iwmr->is_hwreg = false; + return 0; + } + +@@ -3292,9 +3291,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, + * @size: size of memory to register + * @access: Access rights + * @iova_start: start of virtual address for physical buffers ++ * @dma_mr: Flag indicating whether this region is a PD DMA MR + */ + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access, +- u64 *iova_start) ++ u64 *iova_start, bool dma_mr) + { + struct irdma_device *iwdev = to_iwdev(pd->device); + struct irdma_pbl *iwpbl; +@@ -3311,6 +3311,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access + iwpbl = &iwmr->iwpbl; + iwpbl->iwmr = iwmr; + iwmr->type = IRDMA_MEMREG_TYPE_MEM; ++ iwmr->dma_mr = dma_mr; + iwpbl->user_base = *iova_start; + stag = irdma_create_stag(iwdev); + if (!stag) { +@@ -3349,7 +3350,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) + { + u64 kva = 0; + +- return irdma_reg_phys_mr(pd, 0, 0, acc, &kva); ++ return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true); + } + + /** +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index 36ff8dd712f00..cbd8bef68ae4f 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -101,7 +101,8 @@ struct irdma_mr { + }; + struct ib_umem *region; + int access; +- u8 is_hwreg; ++ bool is_hwreg:1; ++ bool dma_mr:1; + u16 type; + u32 page_cnt; + u64 page_size; +-- +2.51.0 + diff --git a/queue-6.17/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-6.17/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..20489e6fb5 --- /dev/null +++ b/queue-6.17/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From b68a78fce86c278d79b7263f08e857d77bfb138a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index 24f455e6dbbc8..42d61b17e6761 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-6.17/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-6.17/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..57fb04e5de --- /dev/null +++ b/queue-6.17/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From 6025d4c0facf30c4a24e3b7eb556081b8e3a90a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index 99a7f1a6c0b58..30a162f68b06b 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3316,11 +3316,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3331,6 +3333,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-6.17/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-6.17/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..7fd9eb49e7 --- /dev/null +++ b/queue-6.17/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From 42fa43069c744e327e0717ac3796842bd3a0917e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index ef4abdea3c2d2..9ecc6343455d6 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1450,7 +1450,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-6.17/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch b/queue-6.17/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch new file mode 100644 index 0000000000..2e595dd052 --- /dev/null +++ b/queue-6.17/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch @@ -0,0 +1,94 @@ +From f684c5ad085e9a3722d3443759669d803f86a3ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:52:03 -0700 +Subject: RDMA/rxe: Fix null deref on srq->rq.queue after resize failure + +From: Zhu Yanjun + +[ Upstream commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 ] + +A NULL pointer dereference can occur in rxe_srq_chk_attr() when +ibv_modify_srq() is invoked twice in succession under certain error +conditions. The first call may fail in rxe_queue_resize(), which leads +rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then +triggers a crash (null deref) when accessing +srq->rq.queue->buf->index_mask. + +Call Trace: + +rxe_modify_srq+0x170/0x480 [rdma_rxe] +? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe] +? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs] +? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs] +ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs] +? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs] +? tryinc_node_nr_active+0xe6/0x150 +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs] +? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs] +? __pfx___raw_spin_lock_irqsave+0x10/0x10 +? __pfx_do_vfs_ioctl+0x10/0x10 +? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0 +? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10 +ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs] +? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs] +__x64_sys_ioctl+0x138/0x1c0 +do_syscall_64+0x82/0x250 +? fdget_pos+0x58/0x4c0 +? ksys_write+0xf3/0x1c0 +? __pfx_ksys_write+0x10/0x10 +? do_syscall_64+0xc8/0x250 +? __pfx_vm_mmap_pgoff+0x10/0x10 +? fget+0x173/0x230 +? fput+0x2a/0x80 +? ksys_mmap_pgoff+0x224/0x4c0 +? do_syscall_64+0xc8/0x250 +? do_user_addr_fault+0x37b/0xfe0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Tested-by: Liu Yi +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c +index 3661cb627d28a..2a234f26ac104 100644 +--- a/drivers/infiniband/sw/rxe/rxe_srq.c ++++ b/drivers/infiniband/sw/rxe/rxe_srq.c +@@ -171,7 +171,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + udata, mi, &srq->rq.producer_lock, + &srq->rq.consumer_lock); + if (err) +- goto err_free; ++ return err; + + srq->rq.max_wr = attr->max_wr; + } +@@ -180,11 +180,6 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + srq->limit = attr->srq_limit; + + return 0; +- +-err_free: +- rxe_queue_cleanup(q); +- srq->rq.queue = NULL; +- return err; + } + + void rxe_srq_cleanup(struct rxe_pool_elem *elem) +-- +2.51.0 + diff --git a/queue-6.17/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-6.17/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..3615853aa1 --- /dev/null +++ b/queue-6.17/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From 7eafd940841faec14575b1f8ada01aa4f7afd072 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 554d83c4af0c1..80d3e7dbe4bc3 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1618,6 +1618,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1637,11 +1639,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-6.17/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..810a853ad3 --- /dev/null +++ b/queue-6.17/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 1fcc47090175c05a09d6c3935a283d572426c7ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 80d3e7dbe4bc3..8d3d6085f0ad8 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1947,6 +1947,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1955,6 +1956,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2497,22 +2499,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2532,11 +2538,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-6.17/regulator-pca9450-fix-error-code-in-probe.patch b/queue-6.17/regulator-pca9450-fix-error-code-in-probe.patch new file mode 100644 index 0000000000..6e9cba8f8d --- /dev/null +++ b/queue-6.17/regulator-pca9450-fix-error-code-in-probe.patch @@ -0,0 +1,42 @@ +From 29686bdad0a0ddb60dabb62b511fdbc420d50409 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 16:35:24 +0300 +Subject: regulator: pca9450: Fix error code in probe() + +From: Dan Carpenter + +[ Upstream commit 670500b41e543c5cb09eb9f7f0e4e26c5b5fdf7e ] + +Return "PTR_ERR(pca9450->sd_vsel_gpio)" instead of "ret". The "ret" +variable is success at this point. + +Fixes: 3ce6f4f943dd ("regulator: pca9450: Fix control register for LDO5") +Signed-off-by: Dan Carpenter +Link: https://patch.msgid.link/aSBqnPoBrsNB1Ale@stanley.mountain +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/pca9450-regulator.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c +index 4be270f4d6c35..91b96dbab328b 100644 +--- a/drivers/regulator/pca9450-regulator.c ++++ b/drivers/regulator/pca9450-regulator.c +@@ -1251,10 +1251,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) + * to this signal (if SION bit is set in IOMUX). + */ + pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN); +- if (IS_ERR(pca9450->sd_vsel_gpio)) { +- dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); +- return ret; +- } ++ if (IS_ERR(pca9450->sd_vsel_gpio)) ++ return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio), ++ "Failed to get SD_VSEL GPIO\n"); + + pca9450->sd_vsel_fixed_low = + of_property_read_bool(ldo5->dev.of_node, "nxp,sd-vsel-fixed-low"); +-- +2.51.0 + diff --git a/queue-6.17/reinstate-resource-avoid-unnecessary-lookups-in-find.patch b/queue-6.17/reinstate-resource-avoid-unnecessary-lookups-in-find.patch new file mode 100644 index 0000000000..e9024ab128 --- /dev/null +++ b/queue-6.17/reinstate-resource-avoid-unnecessary-lookups-in-find.patch @@ -0,0 +1,85 @@ +From 5e9701fbf08d2b5245b39fcf507987109a58f3ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:53:49 +0000 +Subject: Reinstate "resource: avoid unnecessary lookups in + find_next_iomem_res()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilias Stamatis + +[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ] + +Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only +logic") removed an optimization introduced by commit 756398750e11 +("resource: avoid unnecessary lookups in find_next_iomem_res()"). That +was not called out in the message of the first commit explicitly so it's +not entirely clear whether removing the optimization happened +inadvertently or not. + +As the original commit message of the optimization explains there is no +point considering the children of a subtree in find_next_iomem_res() if +the top level range does not match. + +Reinstating the optimization results in performance improvements in +systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem +in such platforms takes 700-1500μs without the optimisation and 10-50μs +with the optimisation. + +Note that even though commit 97523a4edb7b removed the 'sibling_only' +parameter from next_resource(), newer kernels have basically reinstated it +under the name 'skip_children'. + +Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u +Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") +Signed-off-by: Ilias Stamatis +Acked-by: David Hildenbrand (Red Hat) +Cc: Andriy Shevchenko +Cc: Baoquan He +Cc: "Huang, Ying" +Cc: Nadav Amit +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index f9bb5481501a3..ff00e563ecead 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -341,6 +341,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + unsigned long flags, unsigned long desc, + struct resource *res) + { ++ /* Skip children until we find a top level range that matches */ ++ bool skip_children = true; + struct resource *p; + + if (!res) +@@ -351,7 +353,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for_each_resource(&iomem_resource, p, false) { ++ for_each_resource(&iomem_resource, p, skip_children) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -362,6 +364,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + ++ /* ++ * We found a top level range that matches what we are looking ++ * for. Time to start checking children too. ++ */ ++ skip_children = false; ++ + /* Found a match, break */ + if (is_type_match(p, flags, desc)) + break; +-- +2.51.0 + diff --git a/queue-6.17/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch b/queue-6.17/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch new file mode 100644 index 0000000000..d368c55dfc --- /dev/null +++ b/queue-6.17/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch @@ -0,0 +1,67 @@ +From c207ab208ea318364eede433fbfecadb7fdbadd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:33:15 +0800 +Subject: remoteproc: imx_rproc: Fix runtime PM cleanup and improve remove path + +From: Peng Fan + +[ Upstream commit 80405a34e1f8975cdb2d7d8679bca7f768861035 ] + +Proper cleanup should be done when rproc_add() fails by invoking both +pm_runtime_disable() and pm_runtime_put_noidle() to avoid leaving the +device in an inconsistent power state. + +Fix it by adding pm_runtime_put_noidle() and pm_runtime_disable() +in the error path. + +Also Update the remove() callback to use pm_runtime_put_noidle() instead of +pm_runtime_put(), to clearly indicate that only need to restore the usage +count. + +Fixes: a876a3aacc43 ("remoteproc: imx_rproc: detect and attach to pre-booted remote cores") +Cc: Ulf Hansson +Cc: Hiago De Franco +Suggested-by: Ulf Hansson +Signed-off-by: Peng Fan +Reviewed-by: Ulf Hansson +Link: https://lore.kernel.org/r/20250926-imx_rproc_v3-v3-1-4c0ec279cc5f@nxp.com +Signed-off-by: Mathieu Poirier +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/imx_rproc.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c +index a6eef0080ca9e..2eaff813a5b9f 100644 +--- a/drivers/remoteproc/imx_rproc.c ++++ b/drivers/remoteproc/imx_rproc.c +@@ -1174,11 +1174,16 @@ static int imx_rproc_probe(struct platform_device *pdev) + ret = rproc_add(rproc); + if (ret) { + dev_err(dev, "rproc_add failed\n"); +- goto err_put_clk; ++ goto err_put_pm; + } + + return 0; + ++err_put_pm: ++ if (dcfg->method == IMX_RPROC_SCU_API) { ++ pm_runtime_disable(dev); ++ pm_runtime_put_noidle(dev); ++ } + err_put_clk: + clk_disable_unprepare(priv->clk); + err_put_scu: +@@ -1198,7 +1203,7 @@ static void imx_rproc_remove(struct platform_device *pdev) + + if (priv->dcfg->method == IMX_RPROC_SCU_API) { + pm_runtime_disable(priv->dev); +- pm_runtime_put(priv->dev); ++ pm_runtime_put_noidle(priv->dev); + } + clk_disable_unprepare(priv->clk); + rproc_del(rproc); +-- +2.51.0 + diff --git a/queue-6.17/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-6.17/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..96dcee8d46 --- /dev/null +++ b/queue-6.17/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From 8cb2b5d165b3b2f7d93403ba9a46a0c0a0206bdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index 93648734a2f25..74e9e642b5e74 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.17/revert-mtd-rawnand-marvell-fix-layouts.patch b/queue-6.17/revert-mtd-rawnand-marvell-fix-layouts.patch new file mode 100644 index 0000000000..1f3db0b669 --- /dev/null +++ b/queue-6.17/revert-mtd-rawnand-marvell-fix-layouts.patch @@ -0,0 +1,51 @@ +From bfb11cafedc5ae30e6933c0af2fb30a96c94fc03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:41 +1300 +Subject: Revert "mtd: rawnand: marvell: fix layouts" + +From: Aryan Srivastava + +[ Upstream commit fbd72cb463fdea3a0c900dd5d6e813cdebc3a73c ] + +This reverts commit e6a30d0c48a1e8a68f1cc413bee65302ab03ddfb. + +This change resulted in the 8bit ECC layouts having the incorrect amount +of read/write chunks, the last spare bytes chunk would always be missed. + +Fixes: e6a30d0c48a1 ("mtd: rawnand: marvell: fix layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 303b3016a070b..38b7eb5b992c8 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -290,13 +290,16 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { + MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,64, 30), +- MARVELL_LAYOUT( 2048, 512, 16, 4, 4, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 2048, 512, 12, 3, 2, 704, 0, 30,640, 0, 30), ++ MARVELL_LAYOUT( 2048, 512, 16, 5, 4, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), +- MARVELL_LAYOUT( 4096, 512, 8, 4, 4, 1024, 0, 30, 0, 64, 30), +- MARVELL_LAYOUT( 4096, 512, 16, 8, 8, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), ++ MARVELL_LAYOUT( 4096, 512, 12, 6, 5, 704, 0, 30,576, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 16, 9, 8, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 8192, 512, 4, 4, 4, 2048, 0, 30, 0, 0, 0), +- MARVELL_LAYOUT( 8192, 512, 8, 8, 8, 1024, 0, 30, 0, 160, 30), +- MARVELL_LAYOUT( 8192, 512, 16, 16, 16, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 8192, 512, 8, 9, 8, 1024, 0, 30, 0, 160, 30), ++ MARVELL_LAYOUT( 8192, 512, 12, 12, 11, 704, 0, 30,448, 64, 30), ++ MARVELL_LAYOUT( 8192, 512, 16, 17, 16, 512, 0, 30, 0, 32, 30), + }; + + /** +-- +2.51.0 + diff --git a/queue-6.17/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch b/queue-6.17/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch new file mode 100644 index 0000000000..5b7e03d214 --- /dev/null +++ b/queue-6.17/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch @@ -0,0 +1,46 @@ +From ac982b08cd964eec18d5430b74a61ae367c08ba3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:18:39 +0300 +Subject: Revert "wifi: mt76: mt792x: improve monitor interface handling" + +From: Fedor Pchelkin + +[ Upstream commit cdb2941a516cf06929293604e2e0f4c1d6f3541e ] + +This reverts commit 55e95ce469d0c61041bae48b2ebb7fcbf6d1ba7f. + +mt792x drivers don't seem to support multi-radio devices yet. At least +they don't mess with `struct wiphy_radio` at the moment. + +Packet capturing on monitor interface doesn't work after the blamed patch: + + tcpdump -i wls6mon -n -vvv + +Revert the NO_VIRTUAL_MONITOR feature for now to resolve the issue. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 55e95ce469d0 ("wifi: mt76: mt792x: improve monitor interface handling") +Signed-off-by: Fedor Pchelkin +Link: https://patch.msgid.link/20251027111843.38975-1-pchelkin@ispras.ru +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt792x_core.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +index c0e56541a9547..9cad572c34a38 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +@@ -688,7 +688,6 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); +- ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR); + ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); + ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); + +-- +2.51.0 + diff --git a/queue-6.17/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch b/queue-6.17/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch new file mode 100644 index 0000000000..402935f6e6 --- /dev/null +++ b/queue-6.17/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch @@ -0,0 +1,84 @@ +From 6211b5f75e9c3cb8ceff157a2fc0136d4286dfc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 21:35:43 +0800 +Subject: RISC-V: KVM: Fix guest page fault within HLV* instructions + +From: Fangyu Yu + +[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ] + +When executing HLV* instructions at the HS mode, a guest page fault +may occur when a g-stage page table migration between triggering the +virtual instruction exception and executing the HLV* instruction. + +This may be a corner case, and one simpler way to handle this is to +re-execute the instruction where the virtual instruction exception +occurred, and the guest page fault will be automatically handled. + +Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") +Signed-off-by: Fangyu Yu +Reviewed-by: Anup Patel +Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index 97dec18e69892..3dbd6a09d4825 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -424,6 +424,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + return (rc <= 0) ? rc : 1; + } + ++static bool is_load_guest_page_fault(unsigned long scause) ++{ ++ /** ++ * If a g-stage page fault occurs, the direct approach ++ * is to let the g-stage page fault handler handle it ++ * naturally, however, calling the g-stage page fault ++ * handler here seems rather strange. ++ * Considering this is a corner case, we can directly ++ * return to the guest and re-execute the same PC, this ++ * will trigger a g-stage page fault again and then the ++ * regular g-stage page fault handler will populate ++ * g-stage page table. ++ */ ++ return (scause == EXC_LOAD_GUEST_PAGE_FAULT); ++} ++ + /** + * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap + * +@@ -449,6 +465,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + return 1; +@@ -504,6 +522,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +@@ -630,6 +650,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +-- +2.51.0 + diff --git a/queue-6.17/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch b/queue-6.17/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch new file mode 100644 index 0000000000..5dc819e6bf --- /dev/null +++ b/queue-6.17/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch @@ -0,0 +1,229 @@ +From bbc5276d804e714d2f0434ef2c6cdf2cd06642b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 23:27:57 +0000 +Subject: rqspinlock: Enclose lock/unlock within lock entry acquisitions + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit beb7021a6003d9c6a463fffca0d6311efb8e0e66 ] + +Ritesh reported that timeouts occurred frequently for rqspinlock despite +reentrancy on the same lock on the same CPU in [0]. This patch closes +one of the races leading to this behavior, and reduces the frequency of +timeouts. + +We currently have a tiny window between the fast-path cmpxchg and the +grabbing of the lock entry where an NMI could land, attempt the same +lock that was just acquired, and end up timing out. This is not ideal. +Instead, move the lock entry acquisition from the fast path to before +the cmpxchg, and remove the grabbing of the lock entry in the slow path, +assuming it was already taken by the fast path. The TAS fallback is +invoked directly without being preceded by the typical fast path, +therefore we must continue to grab the deadlock detection entry in that +case. + +Case on lock leading to missed AA: + +cmpxchg lock A + +... rqspinlock acquisition of A +... timeout + +grab_held_lock_entry(A) + +There is a similar case when unlocking the lock. If the NMI lands +between the WRITE_ONCE and smp_store_release, it is possible that we end +up in a situation where the NMI fails to diagnose the AA condition, +leading to a timeout. + +Case on unlock leading to missed AA: + +WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) + +... rqspinlock acquisition of A +... timeout + +smp_store_release(A->locked, 0) + +The patch changes the order on unlock to smp_store_release() succeeded +by WRITE_ONCE() of NULL. This avoids the missed AA detection described +above, but may lead to a false positive if the NMI lands between these +two statements, which is acceptable (and preferred over a timeout). + +The original intention of the reverse order on unlock was to prevent the +following possible misdiagnosis of an ABBA scenario: + +grab entry A +lock A +grab entry B +lock B +unlock B + smp_store_release(B->locked, 0) + grab entry B + lock B + grab entry A + lock A + ! + WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) + +If the store release were is after the WRITE_ONCE, the other CPU would +not observe B in the table of the CPU unlocking the lock B. However, +since the threads are obviously participating in an ABBA deadlock, it +is no longer appealing to use the order above since it may lead to a +250 ms timeout due to missed AA detection. + + [0]: https://lore.kernel.org/bpf/CAH6OuBTjG+N=+GGwcpOUbeDN563oz4iVcU3rbse68egp9wj9_A@mail.gmail.com + +Fixes: 0d80e7f951be ("rqspinlock: Choose trylock fallback for NMI waiters") +Reported-by: Ritesh Oedayrajsingh Varma +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251128232802.1031906-2-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/asm-generic/rqspinlock.h | 60 +++++++++++++++++--------------- + kernel/bpf/rqspinlock.c | 15 ++++---- + 2 files changed, 38 insertions(+), 37 deletions(-) + +diff --git a/include/asm-generic/rqspinlock.h b/include/asm-generic/rqspinlock.h +index 6d4244d643df3..0f2dcbbfee2f0 100644 +--- a/include/asm-generic/rqspinlock.h ++++ b/include/asm-generic/rqspinlock.h +@@ -129,8 +129,8 @@ static __always_inline void release_held_lock_entry(void) + * for lock B + * release_held_lock_entry + * +- * try_cmpxchg_acquire for lock A + * grab_held_lock_entry ++ * try_cmpxchg_acquire for lock A + * + * Lack of any ordering means reordering may occur such that dec, inc + * are done before entry is overwritten. This permits a remote lock +@@ -139,13 +139,8 @@ static __always_inline void release_held_lock_entry(void) + * CPU holds a lock it is attempting to acquire, leading to false ABBA + * diagnosis). + * +- * In case of unlock, we will always do a release on the lock word after +- * releasing the entry, ensuring that other CPUs cannot hold the lock +- * (and make conclusions about deadlocks) until the entry has been +- * cleared on the local CPU, preventing any anomalies. Reordering is +- * still possible there, but a remote CPU cannot observe a lock in our +- * table which it is already holding, since visibility entails our +- * release store for the said lock has not retired. ++ * The case of unlock is treated differently due to NMI reentrancy, see ++ * comments in res_spin_unlock. + * + * In theory we don't have a problem if the dec and WRITE_ONCE above get + * reordered with each other, we either notice an empty NULL entry on +@@ -175,10 +170,22 @@ static __always_inline int res_spin_lock(rqspinlock_t *lock) + { + int val = 0; + +- if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL))) { +- grab_held_lock_entry(lock); ++ /* ++ * Grab the deadlock detection entry before doing the cmpxchg, so that ++ * reentrancy due to NMIs between the succeeding cmpxchg and creation of ++ * held lock entry can correctly detect an acquisition attempt in the ++ * interrupted context. ++ * ++ * cmpxchg lock A ++ * ++ * res_spin_lock(A) --> missed AA, leads to timeout ++ * ++ * grab_held_lock_entry(A) ++ */ ++ grab_held_lock_entry(lock); ++ ++ if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL))) + return 0; +- } + return resilient_queued_spin_lock_slowpath(lock, val); + } + +@@ -192,28 +199,25 @@ static __always_inline void res_spin_unlock(rqspinlock_t *lock) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + +- if (unlikely(rqh->cnt > RES_NR_HELD)) +- goto unlock; +- WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL); +-unlock: + /* +- * Release barrier, ensures correct ordering. See release_held_lock_entry +- * for details. Perform release store instead of queued_spin_unlock, +- * since we use this function for test-and-set fallback as well. When we +- * have CONFIG_QUEUED_SPINLOCKS=n, we clear the full 4-byte lockword. ++ * Release barrier, ensures correct ordering. Perform release store ++ * instead of queued_spin_unlock, since we use this function for the TAS ++ * fallback as well. When we have CONFIG_QUEUED_SPINLOCKS=n, we clear ++ * the full 4-byte lockword. + * +- * Like release_held_lock_entry, we can do the release before the dec. +- * We simply care about not seeing the 'lock' in our table from a remote +- * CPU once the lock has been released, which doesn't rely on the dec. ++ * Perform the smp_store_release before clearing the lock entry so that ++ * NMIs landing in the unlock path can correctly detect AA issues. The ++ * opposite order shown below may lead to missed AA checks: + * +- * Unlike smp_wmb(), release is not a two way fence, hence it is +- * possible for a inc to move up and reorder with our clearing of the +- * entry. This isn't a problem however, as for a misdiagnosis of ABBA, +- * the remote CPU needs to hold this lock, which won't be released until +- * the store below is done, which would ensure the entry is overwritten +- * to NULL, etc. ++ * WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) ++ * ++ * res_spin_lock(A) --> missed AA, leads to timeout ++ * ++ * smp_store_release(A->locked, 0) + */ + smp_store_release(&lock->locked, 0); ++ if (likely(rqh->cnt <= RES_NR_HELD)) ++ WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL); + this_cpu_dec(rqspinlock_held_locks.cnt); + } + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index 21be48108e962..f4c534fa4e87b 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -275,6 +275,10 @@ int __lockfunc resilient_tas_spin_lock(rqspinlock_t *lock) + int val, ret = 0; + + RES_INIT_TIMEOUT(ts); ++ /* ++ * The fast path is not invoked for the TAS fallback, so we must grab ++ * the deadlock detection entry here. ++ */ + grab_held_lock_entry(lock); + + /* +@@ -397,10 +401,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + goto queue; + } + +- /* +- * Grab an entry in the held locks array, to enable deadlock detection. +- */ +- grab_held_lock_entry(lock); ++ /* Deadlock detection entry already held after failing fast path. */ + + /* + * We're pending, wait for the owner to go away. +@@ -448,11 +449,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + */ + queue: + lockevent_inc(lock_slowpath); +- /* +- * Grab deadlock detection entry for the queue path. +- */ +- grab_held_lock_entry(lock); +- ++ /* Deadlock detection entry already held after failing fast path. */ + node = this_cpu_ptr(&rqnodes[0].mcs); + idx = node->count++; + tail = encode_tail(smp_processor_id(), idx); +-- +2.51.0 + diff --git a/queue-6.17/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch b/queue-6.17/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch new file mode 100644 index 0000000000..b7f0ebde11 --- /dev/null +++ b/queue-6.17/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch @@ -0,0 +1,87 @@ +From 8ae82df4b20eb0aff24fa3ee07419bd4e5aeeaab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 23:27:59 +0000 +Subject: rqspinlock: Use trylock fallback when per-CPU rqnode is busy + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 81d5a6a438595e46be191d602e5c2d6d73992fdc ] + +In addition to deferring to the trylock fallback in NMIs, only do so +when an rqspinlock waiter is queued on the current CPU. This is detected +by noticing a non-zero node index. This allows NMI waiters to join the +waiter queue if it isn't interrupting an existing rqspinlock waiter, and +increase the chances of fairly obtaining the lock, performing deadlock +detection as the head, and not being starved while attempting the +trylock. + +The trylock path in particular is unlikely to succeed under contention, +as it relies on the lock word becoming 0, which indicates no contention. +This means that the most likely result for NMIs attempting a trylock is +a timeout under contention if they don't hit an AA or ABBA case. + +The core problem being addressed through the fixed commit was removing +the dependency edge between an NMI queue waiter and the queue waiter it +is interrupting. Whenever a circular dependency forms, and with no way +to break it (as non-head waiters don't poll for deadlocks or timeouts), +we would enter into a deadlock. A trylock either breaks such an edge by +probing for deadlocks, and finally terminating the waiting loop using a +timeout. + +By excluding queueing on CPUs where the node index is non-zero for NMIs, +this sort of dependency is broken. The CPU enters the trylock path for +those cases, and falls back to deadlock checks and timeouts. However, in +other case where it doesn't interrupt the CPU in the slow path while its +queued on the lock, it can join the queue as a normal waiter, and avoid +trylock associated starvation and subsequent timeouts. + +There are a few remaining cases here that matter: the NMI can still +preempt the owner in its critical section, and if it queues as a +non-head waiter, it can end up impeding the progress of the owner. While +this won't deadlock, since the head waiter will eventually signal the +NMI waiter to either stop (due to a timeout), it can still lead to long +timeouts. These gaps will be addressed in subsequent commits. + +Note that while the node count detection approach is less conservative +than simply deferring NMIs to trylock, it is going to return errors +where attempts to lock B in NMI happen while waiters for lock A are in a +lower context on the same CPU. However, this only occurs when the lower +context is queued in the slow path, and the NMI attempt can proceed +without failure in all other cases. To continue to prevent AA deadlocks +(or ABBA in a similar NMI interrupting lower context pattern), we'd need +a more fleshed out algorithm to unlink NMI waiters after they queue and +detect such cases. However, all that complexity isn't appealing yet to +reduce the failure rate in the small window inside the slow path. + +It is important to note that reentrancy in the slow path can also happen +through trace_contention_{begin,end}, but in those cases, unlike an NMI, +the forward progress of the head waiter (or the predecessor in general) +is not being blocked. + +Fixes: 0d80e7f951be ("rqspinlock: Choose trylock fallback for NMI waiters") +Reported-by: Ritesh Oedayrajsingh Varma +Suggested-by: Alexei Starovoitov +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251128232802.1031906-4-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/rqspinlock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index f4c534fa4e87b..3faf9cbd6c753 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -465,7 +465,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + * any MCS node. This is not the most elegant solution, but is + * simple enough. + */ +- if (unlikely(idx >= _Q_MAX_NODES || in_nmi())) { ++ if (unlikely(idx >= _Q_MAX_NODES || (in_nmi() && idx > 0))) { + lockevent_inc(lock_no_node); + RES_RESET_TIMEOUT(ts, RES_DEF_TIMEOUT); + while (!queued_spin_trylock(lock)) { +-- +2.51.0 + diff --git a/queue-6.17/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-6.17/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..7340fff45d --- /dev/null +++ b/queue-6.17/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From a1cf2bf28d97dfc90693e9f219677746bc08f3cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 65f1a127cc3f6..dfd5d0f61a70d 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -2484,15 +2484,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-6.17/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch b/queue-6.17/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch new file mode 100644 index 0000000000..60c5a25efe --- /dev/null +++ b/queue-6.17/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch @@ -0,0 +1,160 @@ +From 9f7869045848b6669ac60170cd7e7ce3429c1859 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 16:59:16 +0100 +Subject: s390/fpu: Fix false-positive kmsan report in fpu_vstl() + +From: Aleksei Nikiforov + +[ Upstream commit 14e4e4175b64dd9216b522f6ece8af6997d063b2 ] + +A false-positive kmsan report is detected when running ping command. + +An inline assembly instruction 'vstl' can write varied amount of bytes +depending on value of 'index' argument. If 'index' > 0, 'vstl' writes +at least 2 bytes. + +clang generates kmsan write helper call depending on inline assembly +constraints. Constraints are evaluated compile-time, but value of +'index' argument is known only at runtime. + +clang currently generates call to __msan_instrument_asm_store with 1 byte +as size. Manually call kmsan function to indicate correct amount of bytes +written and fix false-positive report. + +This change fixes following kmsan reports: + +[ 36.563119] ===================================================== +[ 36.563594] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 36.563852] virtqueue_add+0x35c6/0x7c70 +[ 36.564016] virtqueue_add_outbuf+0xa0/0xb0 +[ 36.564266] start_xmit+0x288c/0x4a20 +[ 36.564460] dev_hard_start_xmit+0x302/0x900 +[ 36.564649] sch_direct_xmit+0x340/0xea0 +[ 36.564894] __dev_queue_xmit+0x2e94/0x59b0 +[ 36.565058] neigh_resolve_output+0x936/0xb40 +[ 36.565278] __neigh_update+0x2f66/0x3a60 +[ 36.565499] neigh_update+0x52/0x60 +[ 36.565683] arp_process+0x1588/0x2de0 +[ 36.565916] NF_HOOK+0x1da/0x240 +[ 36.566087] arp_rcv+0x3e4/0x6e0 +[ 36.566306] __netif_receive_skb_list_core+0x1374/0x15a0 +[ 36.566527] netif_receive_skb_list_internal+0x1116/0x17d0 +[ 36.566710] napi_complete_done+0x376/0x740 +[ 36.566918] virtnet_poll+0x1bae/0x2910 +[ 36.567130] __napi_poll+0xf4/0x830 +[ 36.567294] net_rx_action+0x97c/0x1ed0 +[ 36.567556] handle_softirqs+0x306/0xe10 +[ 36.567731] irq_exit_rcu+0x14c/0x2e0 +[ 36.567910] do_io_irq+0xd4/0x120 +[ 36.568139] io_int_handler+0xc2/0xe8 +[ 36.568299] arch_cpu_idle+0xb0/0xc0 +[ 36.568540] arch_cpu_idle+0x76/0xc0 +[ 36.568726] default_idle_call+0x40/0x70 +[ 36.568953] do_idle+0x1d6/0x390 +[ 36.569486] cpu_startup_entry+0x9a/0xb0 +[ 36.569745] rest_init+0x1ea/0x290 +[ 36.570029] start_kernel+0x95e/0xb90 +[ 36.570348] startup_continue+0x2e/0x40 +[ 36.570703] +[ 36.570798] Uninit was created at: +[ 36.571002] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 36.571261] kmalloc_reserve+0x12a/0x470 +[ 36.571553] __alloc_skb+0x310/0x860 +[ 36.571844] __ip_append_data+0x483e/0x6a30 +[ 36.572170] ip_append_data+0x11c/0x1e0 +[ 36.572477] raw_sendmsg+0x1c8c/0x2180 +[ 36.572818] inet_sendmsg+0xe6/0x190 +[ 36.573142] __sys_sendto+0x55e/0x8e0 +[ 36.573392] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 36.573571] __do_syscall+0x12e/0x240 +[ 36.573823] system_call+0x6e/0x90 +[ 36.573976] +[ 36.574017] Byte 35 of 98 is uninitialized +[ 36.574082] Memory access of size 98 starts at 0000000007aa0012 +[ 36.574218] +[ 36.574325] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G B N 6.17.0-dirty #16 NONE +[ 36.574541] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 36.574617] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 36.574755] ===================================================== + +[ 63.532541] ===================================================== +[ 63.533639] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 63.533989] virtqueue_add+0x35c6/0x7c70 +[ 63.534940] virtqueue_add_outbuf+0xa0/0xb0 +[ 63.535861] start_xmit+0x288c/0x4a20 +[ 63.536708] dev_hard_start_xmit+0x302/0x900 +[ 63.537020] sch_direct_xmit+0x340/0xea0 +[ 63.537997] __dev_queue_xmit+0x2e94/0x59b0 +[ 63.538819] neigh_resolve_output+0x936/0xb40 +[ 63.539793] ip_finish_output2+0x1ee2/0x2200 +[ 63.540784] __ip_finish_output+0x272/0x7a0 +[ 63.541765] ip_finish_output+0x4e/0x5e0 +[ 63.542791] ip_output+0x166/0x410 +[ 63.543771] ip_push_pending_frames+0x1a2/0x470 +[ 63.544753] raw_sendmsg+0x1f06/0x2180 +[ 63.545033] inet_sendmsg+0xe6/0x190 +[ 63.546006] __sys_sendto+0x55e/0x8e0 +[ 63.546859] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.547730] __do_syscall+0x12e/0x240 +[ 63.548019] system_call+0x6e/0x90 +[ 63.548989] +[ 63.549779] Uninit was created at: +[ 63.550691] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 63.550975] kmalloc_reserve+0x12a/0x470 +[ 63.551969] __alloc_skb+0x310/0x860 +[ 63.552949] __ip_append_data+0x483e/0x6a30 +[ 63.553902] ip_append_data+0x11c/0x1e0 +[ 63.554912] raw_sendmsg+0x1c8c/0x2180 +[ 63.556719] inet_sendmsg+0xe6/0x190 +[ 63.557534] __sys_sendto+0x55e/0x8e0 +[ 63.557875] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.558869] __do_syscall+0x12e/0x240 +[ 63.559832] system_call+0x6e/0x90 +[ 63.560780] +[ 63.560972] Byte 35 of 98 is uninitialized +[ 63.561741] Memory access of size 98 starts at 0000000005704312 +[ 63.561950] +[ 63.562824] CPU: 3 UID: 0 PID: 192 Comm: ping Tainted: G B N 6.17.0-dirty #16 NONE +[ 63.563868] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 63.564751] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 63.564986] ===================================================== + +Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()") +Signed-off-by: Aleksei Nikiforov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/fpu-insn.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h +index 135bb89c0a893..8f2dd6e879ff6 100644 +--- a/arch/s390/include/asm/fpu-insn.h ++++ b/arch/s390/include/asm/fpu-insn.h +@@ -12,6 +12,7 @@ + #ifndef __ASSEMBLER__ + + #include ++#include + #include + + asm(".include \"asm/fpu-insn-asm.h\"\n"); +@@ -393,6 +394,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) + : [vxr] "=Q" (*(u8 *)vxr) + : [index] "d" (index), [v1] "I" (v1) + : "memory"); ++ kmsan_unpoison_memory(vxr, size); + } + + #else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ +@@ -409,6 +411,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) + : [vxr] "=R" (*(u8 *)vxr) + : [index] "d" (index), [v1] "I" (v1) + : "memory", "1"); ++ kmsan_unpoison_memory(vxr, size); + } + + #endif /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ +-- +2.51.0 + diff --git a/queue-6.17/s390-smp-fix-fallback-cpu-detection.patch b/queue-6.17/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..164584accc --- /dev/null +++ b/queue-6.17/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From e78b7f9a55047696808acf82ad248735c0cf8fa8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index e88ebe5339fc4..4b0ce76c6bbd9 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -697,6 +697,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-6.17/sched-core-fix-psi_dequeue-for-proxy-execution.patch b/queue-6.17/sched-core-fix-psi_dequeue-for-proxy-execution.patch new file mode 100644 index 0000000000..bb068f7812 --- /dev/null +++ b/queue-6.17/sched-core-fix-psi_dequeue-for-proxy-execution.patch @@ -0,0 +1,82 @@ +From e1a819766753e0db1efc0d905e5993b14581daa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Dec 2025 01:27:09 +0000 +Subject: sched/core: Fix psi_dequeue() for Proxy Execution + +From: John Stultz + +[ Upstream commit c2ae8b0df2d1bb7a063f9e356e4e9a06cd4afe11 ] + +Currently, if the sleep flag is set, psi_dequeue() doesn't +change any of the psi_flags. + +This is because psi_task_switch() will clear TSK_ONCPU as well +as other potential flags (TSK_RUNNING), and the assumption is +that a voluntary sleep always consists of a task being dequeued +followed shortly there after with a psi_sched_switch() call. + +Proxy Execution changes this expectation, as mutex-blocked tasks +that would normally sleep stay on the runqueue. But in the case +where the mutex-owning task goes to sleep, or the owner is on a +remote cpu, we will then deactivate the blocked task shortly +after. + +In that situation, the mutex-blocked task will have had its +TSK_ONCPU cleared when it was switched off the cpu, but it will +stay TSK_RUNNING. Then if we later dequeue it (as currently done +if we hit a case find_proxy_task() can't yet handle, such as the +case of the owner being on another rq or a sleeping owner) +psi_dequeue() won't change any state (leaving it TSK_RUNNING), +as it incorrectly expects a psi_task_switch() call to +immediately follow. + +Later on when the task get woken/re-enqueued, and psi_flags are +set for TSK_RUNNING, we hit an error as the task is already +TSK_RUNNING: + + psi: inconsistent task state! task=188:kworker/28:0 cpu=28 psi_flags=4 clear=0 set=4 + +To resolve this, extend the logic in psi_dequeue() so that +if the sleep flag is set, we also check if psi_flags have +TSK_ONCPU set (meaning the psi_task_switch is imminent) before +we do the shortcut return. + +If TSK_ONCPU is not set, that means we've already switched away, +and this psi_dequeue call needs to clear the flags. + +Fixes: be41bde4c3a8 ("sched: Add an initial sketch of the find_proxy_task() function") +Reported-by: K Prateek Nayak +Signed-off-by: John Stultz +Signed-off-by: Ingo Molnar +Tested-by: K Prateek Nayak +Tested-by: Haiyue Wang +Acked-by: Johannes Weiner +Link: https://patch.msgid.link/20251205012721.756394-1-jstultz@google.com +Closes: https://lore.kernel.org/lkml/20251117185550.365156-1-kprateek.nayak@amd.com/ +Signed-off-by: Sasha Levin +--- + kernel/sched/stats.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h +index 26f3fd4d34cea..73bd6bca4d310 100644 +--- a/kernel/sched/stats.h ++++ b/kernel/sched/stats.h +@@ -180,8 +180,13 @@ static inline void psi_dequeue(struct task_struct *p, int flags) + * avoid walking all ancestors twice, psi_task_switch() handles + * TSK_RUNNING and TSK_IOWAIT for us when it moves TSK_ONCPU. + * Do nothing here. ++ * ++ * In the SCHED_PROXY_EXECUTION case we may do sleeping ++ * dequeues that are not followed by a task switch, so check ++ * TSK_ONCPU is set to ensure the task switch is imminent. ++ * Otherwise clear the flags as usual. + */ +- if (flags & DEQUEUE_SLEEP) ++ if ((flags & DEQUEUE_SLEEP) && (p->psi_flags & TSK_ONCPU)) + return; + + /* +-- +2.51.0 + diff --git a/queue-6.17/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch b/queue-6.17/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch new file mode 100644 index 0000000000..115aa266bd --- /dev/null +++ b/queue-6.17/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch @@ -0,0 +1,57 @@ +From a472c15df48a02969eb7fbe17387d538aa5b4043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Aug 2025 10:22:07 +0800 +Subject: sched/fair: Fix unfairness caused by stalled tg_load_avg_contrib when + the last task migrates out + +From: xupengbo + +[ Upstream commit ca125231dd29fc0678dd3622e9cdea80a51dffe4 ] + +When a task is migrated out, there is a probability that the tg->load_avg +value will become abnormal. The reason is as follows: + +1. Due to the 1ms update period limitation in update_tg_load_avg(), there + is a possibility that the reduced load_avg is not updated to tg->load_avg + when a task migrates out. + +2. Even though __update_blocked_fair() traverses the leaf_cfs_rq_list and + calls update_tg_load_avg() for cfs_rqs that are not fully decayed, the key + function cfs_rq_is_decayed() does not check whether + cfs->tg_load_avg_contrib is null. Consequently, in some cases, + __update_blocked_fair() removes cfs_rqs whose avg.load_avg has not been + updated to tg->load_avg. + +Add a check of cfs_rq->tg_load_avg_contrib in cfs_rq_is_decayed(), +which fixes the case (2.) mentioned above. + +Fixes: 1528c661c24b ("sched/fair: Ratelimit update to tg->load_avg") +Signed-off-by: xupengbo +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Reviewed-by: Aaron Lu +Reviewed-by: Vincent Guittot +Tested-by: Aaron Lu +Link: https://patch.msgid.link/20250827022208.14487-1-xupengbo@oppo.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 35b98cad06515..434df3fb6c443 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4062,6 +4062,9 @@ static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) + if (child_cfs_rq_on_list(cfs_rq)) + return false; + ++ if (cfs_rq->tg_load_avg_contrib) ++ return false; ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.17/sched-fair-forfeit-vruntime-on-yield.patch b/queue-6.17/sched-fair-forfeit-vruntime-on-yield.patch new file mode 100644 index 0000000000..34bbd727d3 --- /dev/null +++ b/queue-6.17/sched-fair-forfeit-vruntime-on-yield.patch @@ -0,0 +1,68 @@ +From b89d3036f4fd63436376569499a6d928c2368140 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:05:28 +0200 +Subject: sched/fair: Forfeit vruntime on yield + +From: Fernand Sieber + +[ Upstream commit 79104becf42baeeb4a3f2b106f954b9fc7c10a3c ] + +If a task yields, the scheduler may decide to pick it again. The task in +turn may decide to yield immediately or shortly after, leading to a tight +loop of yields. + +If there's another runnable task as this point, the deadline will be +increased by the slice at each loop. This can cause the deadline to runaway +pretty quickly, and subsequent elevated run delays later on as the task +doesn't get picked again. The reason the scheduler can pick the same task +again and again despite its deadline increasing is because it may be the +only eligible task at that point. + +Fix this by making the task forfeiting its remaining vruntime and pushing +the deadline one slice ahead. This implements yield behavior more +authentically. + +We limit the forfeiting to eligible tasks. This is because core scheduling +prefers running ineligible tasks rather than force idling. As such, without +the condition, we can end up on a yield loop which makes the vruntime +increase rapidly, leading to anomalous run delays later down the line. + +Fixes: 147f3efaa24182 ("sched/fair: Implement an EEVDF-like scheduling policy") +Signed-off-by: Fernand Sieber +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20250401123622.584018-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250911095113.203439-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250916140228.452231-1-sieberf@amazon.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 4770d25ae2406..35b98cad06515 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8919,7 +8919,19 @@ static void yield_task_fair(struct rq *rq) + */ + rq_clock_skip_update(rq); + +- se->deadline += calc_delta_fair(se->slice, se); ++ /* ++ * Forfeit the remaining vruntime, only if the entity is eligible. This ++ * condition is necessary because in core scheduling we prefer to run ++ * ineligible tasks rather than force idling. If this happens we may ++ * end up in a loop where the core scheduler picks the yielding task, ++ * which yields immediately again; without the condition the vruntime ++ * ends up quickly running away. ++ */ ++ if (entity_eligible(cfs_rq, se)) { ++ se->vruntime = se->deadline; ++ se->deadline += calc_delta_fair(se->slice, se); ++ update_min_vruntime(cfs_rq); ++ } + } + + static bool yield_to_task_fair(struct rq *rq, struct task_struct *p) +-- +2.51.0 + diff --git a/queue-6.17/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch b/queue-6.17/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch new file mode 100644 index 0000000000..bc6f3659d8 --- /dev/null +++ b/queue-6.17/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch @@ -0,0 +1,51 @@ +From 5b6b695099dd84b8e9e518c183bfefdabc3413f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 15:12:46 +0000 +Subject: scsi: qla2xxx: Fix improper freeing of purex item + +From: Zilin Guan + +[ Upstream commit 78b1a242fe612a755f2158fd206ee6bb577d18ca ] + +In qla2xxx_process_purls_iocb(), an item is allocated via +qla27xx_copy_multiple_pkt(), which internally calls +qla24xx_alloc_purex_item(). + +The qla24xx_alloc_purex_item() function may return a pre-allocated item +from a per-adapter pool for small allocations, instead of dynamically +allocating memory with kzalloc(). + +An error handling path in qla2xxx_process_purls_iocb() incorrectly uses +kfree() to release the item. If the item was from the pre-allocated +pool, calling kfree() on it is a bug that can lead to memory corruption. + +Fix this by using the correct deallocation function, +qla24xx_free_purex_item(), which properly handles both dynamically +allocated and pre-allocated items. + +Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") +Signed-off-by: Zilin Guan +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_nvme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 316594aa40cc5..42eb65a62f1f3 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) + a.reason = FCNVME_RJT_RC_LOGIC; + a.explanation = FCNVME_RJT_EXP_NONE; + xmt_reject = true; +- kfree(item); ++ qla24xx_free_purex_item(item); + goto out; + } + +-- +2.51.0 + diff --git a/queue-6.17/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-6.17/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..6a9f69f0d5 --- /dev/null +++ b/queue-6.17/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From f502467d2e8979b82ec6e92fdcb861e756cc37fc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-6.17/scsi-smartpqi-fix-device-resources-accessed-after-de.patch b/queue-6.17/scsi-smartpqi-fix-device-resources-accessed-after-de.patch new file mode 100644 index 0000000000..f5b97caf82 --- /dev/null +++ b/queue-6.17/scsi-smartpqi-fix-device-resources-accessed-after-de.patch @@ -0,0 +1,94 @@ +From 8ff92f4ff5ad70471153dd6a5f606ce57f25dd25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 10:38:20 -0600 +Subject: scsi: smartpqi: Fix device resources accessed after device removal + +From: Mike McGowen + +[ Upstream commit b518e86d1a70a88f6592a7c396cf1b93493d1aab ] + +Correct possible race conditions during device removal. + +Previously, a scheduled work item to reset a LUN could still execute +after the device was removed, leading to use-after-free and other +resource access issues. + +This race condition occurs because the abort handler may schedule a LUN +reset concurrently with device removal via sdev_destroy(), leading to +use-after-free and improper access to freed resources. + + - Check in the device reset handler if the device is still present in + the controller's SCSI device list before running; if not, the reset + is skipped. + + - Cancel any pending TMF work that has not started in sdev_destroy(). + + - Ensure device freeing in sdev_destroy() is done while holding the + LUN reset mutex to avoid races with ongoing resets. + +Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 125944941601e..9f4f6e74f3e38 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6409,10 +6409,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev + + static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { ++ unsigned long flags; + int rc; + + mutex_lock(&ctrl_info->lun_reset_mutex); + ++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); ++ if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { ++ dev_warn(&ctrl_info->pci_dev->dev, ++ "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%u SCSI cmd at %p due to cmd opcode 0x%02x\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, lun, scmd, scsi_opcode); +@@ -6593,7 +6605,9 @@ static void pqi_sdev_destroy(struct scsi_device *sdev) + { + struct pqi_ctrl_info *ctrl_info; + struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; + int mutex_acquired; ++ unsigned int lun; + unsigned long flags; + + ctrl_info = shost_to_hba(sdev->host); +@@ -6620,8 +6634,13 @@ static void pqi_sdev_destroy(struct scsi_device *sdev) + + mutex_unlock(&ctrl_info->scan_mutex); + ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ cancel_work_sync(&tmf_work->work_struct); ++ ++ mutex_lock(&ctrl_info->lun_reset_mutex); + pqi_dev_info(ctrl_info, "removed", device); + pqi_free_device(device); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); + } + + static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) +-- +2.51.0 + diff --git a/queue-6.17/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-6.17/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..2e1dc3c1aa --- /dev/null +++ b/queue-6.17/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From 20340efef3eea91530ceb9a99b8b84aec2751bf0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index 63ed7f9aaa937..34a557297feff 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1844,6 +1844,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-6.17/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-6.17/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..b0e3953ba0 --- /dev/null +++ b/queue-6.17/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From 61d944f89a46d77701bdd8f633ed76fc192e41ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index b19acd662726d..1bd28482e7cb3 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2772,7 +2772,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-6.17/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch b/queue-6.17/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch new file mode 100644 index 0000000000..2315dd2c65 --- /dev/null +++ b/queue-6.17/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch @@ -0,0 +1,171 @@ +From 8059d365b1df0ecd4a3f8770f48128bba17e8e5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 17:12:53 -0500 +Subject: scsi: target: Fix LUN/device R/W and total command stats + +From: Mike Christie + +[ Upstream commit 95aa2041c654161d1b5c1eca5379d67d91ef1cf2 ] + +In commit 9cf2317b795d ("scsi: target: Move I/O path stats to per CPU") +I saw we sometimes use %u and also misread the spec. As a result I +thought all the stats were supposed to be 32-bit only. However, for the +majority of cases we support currently, the spec specifies u64 bit +stats. This patch converts the stats changed in the commit above to u64. + +Fixes: 9cf2317b795d ("scsi: target: Move I/O path stats to per CPU") +Signed-off-by: Mike Christie +Reviewed-by: Dmitry Bogdanov +Link: https://patch.msgid.link/20250917221338.14813-2-michael.christie@oracle.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_stat.c | 24 ++++++++++++------------ + include/target/target_core_base.h | 12 ++++++------ + 2 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c +index 6bdf2d8bd6942..4fdc307ea38bc 100644 +--- a/drivers/target/target_core_stat.c ++++ b/drivers/target/target_core_stat.c +@@ -282,7 +282,7 @@ static ssize_t target_stat_lu_num_cmds_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 cmds = 0; ++ u64 cmds = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -290,7 +290,7 @@ static ssize_t target_stat_lu_num_cmds_show(struct config_item *item, + } + + /* scsiLuNumCommands */ +- return snprintf(page, PAGE_SIZE, "%u\n", cmds); ++ return snprintf(page, PAGE_SIZE, "%llu\n", cmds); + } + + static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, +@@ -299,7 +299,7 @@ static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 bytes = 0; ++ u64 bytes = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -307,7 +307,7 @@ static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, + } + + /* scsiLuReadMegaBytes */ +- return snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ return snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + } + + static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, +@@ -316,7 +316,7 @@ static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 bytes = 0; ++ u64 bytes = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -324,7 +324,7 @@ static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, + } + + /* scsiLuWrittenMegaBytes */ +- return snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ return snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + } + + static ssize_t target_stat_lu_resets_show(struct config_item *item, char *page) +@@ -1044,7 +1044,7 @@ static ssize_t target_stat_auth_num_cmds_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 cmds = 0; ++ u64 cmds = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1059,7 +1059,7 @@ static ssize_t target_stat_auth_num_cmds_show(struct config_item *item, + } + + /* scsiAuthIntrOutCommands */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", cmds); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", cmds); + rcu_read_unlock(); + return ret; + } +@@ -1073,7 +1073,7 @@ static ssize_t target_stat_auth_read_mbytes_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 bytes = 0; ++ u64 bytes = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1088,7 +1088,7 @@ static ssize_t target_stat_auth_read_mbytes_show(struct config_item *item, + } + + /* scsiAuthIntrReadMegaBytes */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + rcu_read_unlock(); + return ret; + } +@@ -1102,7 +1102,7 @@ static ssize_t target_stat_auth_write_mbytes_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 bytes = 0; ++ u64 bytes = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1117,7 +1117,7 @@ static ssize_t target_stat_auth_write_mbytes_show(struct config_item *item, + } + + /* scsiAuthIntrWrittenMegaBytes */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + rcu_read_unlock(); + return ret; + } +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index c4d9116904aa0..27e1f9d5f0c6c 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -671,9 +671,9 @@ struct se_lun_acl { + }; + + struct se_dev_entry_io_stats { +- u32 total_cmds; +- u32 read_bytes; +- u32 write_bytes; ++ u64 total_cmds; ++ u64 read_bytes; ++ u64 write_bytes; + }; + + struct se_dev_entry { +@@ -806,9 +806,9 @@ struct se_device_queue { + }; + + struct se_dev_io_stats { +- u32 total_cmds; +- u32 read_bytes; +- u32 write_bytes; ++ u64 total_cmds; ++ u64 read_bytes; ++ u64 write_bytes; + }; + + struct se_device { +-- +2.51.0 + diff --git a/queue-6.17/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch b/queue-6.17/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch new file mode 100644 index 0000000000..73389da2b9 --- /dev/null +++ b/queue-6.17/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch @@ -0,0 +1,46 @@ +From e400ab6b27d47c8eb16255b60e03b88ed56880cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 00:05:17 +0100 +Subject: scsi: ufs: core: fix incorrect buffer duplication in + ufshcd_read_string_desc() + +From: Bean Huo + +[ Upstream commit d794b499f948801f54d67ddbc34a6eac5a6d150a ] + +The function ufshcd_read_string_desc() was duplicating memory starting +from the beginning of struct uc_string_id, which included the length and +type fields. As a result, the allocated buffer contained unwanted +metadata in addition to the string itself. + +The correct behavior is to duplicate only the Unicode character array in +the structure. Update the code so that only the actual string content is +copied into the new buffer. + +Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Bean Huo +Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index f69a237262353..9331ee3599050 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3831,7 +3831,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + str[ret++] = '\0'; + + } else { +- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); ++ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + goto out; +-- +2.51.0 + diff --git a/queue-6.17/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch b/queue-6.17/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch new file mode 100644 index 0000000000..f1291a3064 --- /dev/null +++ b/queue-6.17/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch @@ -0,0 +1,51 @@ +From ea172b6c0179dfab71b101188f0a96f860221693 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 13:00:58 -0700 +Subject: scsi: ufs: core: Move the ufshcd_enable_intr() declaration + +From: Bart Van Assche + +[ Upstream commit b30006b5bec1dcba207bc42e7f7cd96a568acc27 ] + +ufshcd_enable_intr() is not exported and hence should not be declared in +include/ufs/ufshcd.h. + +Fixes: 253757797973 ("scsi: ufs: core: Change MCQ interrupt enable flow") +Signed-off-by: Bart Van Assche +Reviewed-by: Peter Wang +Link: https://patch.msgid.link/20251014200118.3390839-7-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd-priv.h | 2 ++ + include/ufs/ufshcd.h | 1 - + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h +index d0a2c963a27d3..1f0d38aa37f92 100644 +--- a/drivers/ufs/core/ufshcd-priv.h ++++ b/drivers/ufs/core/ufshcd-priv.h +@@ -6,6 +6,8 @@ + #include + #include + ++void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs); ++ + static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba) + { + return !hba->shutting_down; +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index ace8b9c33f1f9..0303103e8cac1 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -1328,7 +1328,6 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) + + void ufshcd_enable_irq(struct ufs_hba *hba); + void ufshcd_disable_irq(struct ufs_hba *hba); +-void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs); + int ufshcd_alloc_host(struct device *, struct ufs_hba **); + int ufshcd_hba_enable(struct ufs_hba *hba); + int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int); +-- +2.51.0 + diff --git a/queue-6.17/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch b/queue-6.17/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch new file mode 100644 index 0000000000..349d9b5f00 --- /dev/null +++ b/queue-6.17/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch @@ -0,0 +1,87 @@ +From 849e0cf3b0abe537e4d679c20935861300d70009 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:55 +0800 +Subject: scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable + notify + +From: Shawn Lin + +[ Upstream commit b0ee72db9132bd19b1b80152b35e0cf6a6cbd9f2 ] + +This fixes the dme-reset failed when doing recovery. Because device +reset is not enough, we could occasionally see the error below: + +ufshcd-rockchip 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout +ufshcd-rockchip 2a2d0000.ufs: dme-reset: error code -110 +ufshcd-rockchip 2a2d0000.ufs: DME_RESET failed +ufshcd-rockchip 2a2d0000.ufs: ufshcd_host_reset_and_restore: Host init failed -110 + +Fix this by resetting the controller on PRE_CHANGE stage of hce enable +notify. + +Fixes: d3cbe455d6eb ("scsi: ufs: rockchip: Initial support for UFS") +Signed-off-by: Shawn Lin +Link: https://patch.msgid.link/1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/host/ufs-rockchip.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c +index 8754085dd0ccf..8cecb28cdce41 100644 +--- a/drivers/ufs/host/ufs-rockchip.c ++++ b/drivers/ufs/host/ufs-rockchip.c +@@ -20,9 +20,17 @@ + #include "ufshcd-pltfrm.h" + #include "ufs-rockchip.h" + ++static void ufs_rockchip_controller_reset(struct ufs_rockchip_host *host) ++{ ++ reset_control_assert(host->rst); ++ udelay(1); ++ reset_control_deassert(host->rst); ++} ++ + static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) + { ++ struct ufs_rockchip_host *host = ufshcd_get_variant(hba); + int err = 0; + + if (status == POST_CHANGE) { +@@ -37,6 +45,9 @@ static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, + return ufshcd_vops_phy_initialization(hba); + } + ++ /* PRE_CHANGE */ ++ ufs_rockchip_controller_reset(host); ++ + return 0; + } + +@@ -156,9 +167,7 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba) + return dev_err_probe(dev, PTR_ERR(host->rst), + "failed to get reset control\n"); + +- reset_control_assert(host->rst); +- udelay(1); +- reset_control_deassert(host->rst); ++ ufs_rockchip_controller_reset(host); + + host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out"); + if (IS_ERR(host->ref_out_clk)) +@@ -282,9 +291,7 @@ static int ufs_rockchip_runtime_resume(struct device *dev) + return err; + } + +- reset_control_assert(host->rst); +- udelay(1); +- reset_control_deassert(host->rst); ++ ufs_rockchip_controller_reset(host); + + return ufshcd_runtime_resume(dev); + } +-- +2.51.0 + diff --git a/queue-6.17/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-6.17/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..43f5b34e57 --- /dev/null +++ b/queue-6.17/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From f12b191a5dc1f877ea898602800a7bc37a7d4f2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index 4921416434f9a..1c465365daf24 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1554,8 +1554,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5112,9 +5110,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Triggered when there are no references on the socket anymore */ +-- +2.51.0 + diff --git a/queue-6.17/selftests-bonding-add-delay-before-each-xvlan_over_b.patch b/queue-6.17/selftests-bonding-add-delay-before-each-xvlan_over_b.patch new file mode 100644 index 0000000000..baa43b7ca3 --- /dev/null +++ b/queue-6.17/selftests-bonding-add-delay-before-each-xvlan_over_b.patch @@ -0,0 +1,47 @@ +From 95251b0cd9e504692ba4f15674d279487e73b068 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:33:10 +0000 +Subject: selftests: bonding: add delay before each xvlan_over_bond + connectivity check + +From: Hangbin Liu + +[ Upstream commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d ] + +Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular +kernel, while the tests consistently pass on a debug kernel. This suggests +a timing-sensitive issue. + +To mitigate this, introduce a short sleep before each xvlan_over_bond +connectivity check. The delay helps ensure neighbor and route cache +have fully converged before verifying connectivity. + +The sleep interval is kept minimal since check_connection() is invoked +nearly 100 times during the test. + +Fixes: 246af950b940 ("selftests: bonding: add macvlan over bond testing") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/netdev/20251114082014.750edfad@kernel.org +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251127143310.47740-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +index c4711272fe45d..559f300f965aa 100755 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -30,6 +30,7 @@ check_connection() + local message=${3} + RET=0 + ++ sleep 0.25 + ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null + check_err $? "ping failed" + log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" +-- +2.51.0 + diff --git a/queue-6.17/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-6.17/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..3803b1802c --- /dev/null +++ b/queue-6.17/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 6b68a4eeaaadbb9ef22b0f7b33b3491d7eea96ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 1702aa592c2c2..7ac4d5a488aa5 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -206,6 +206,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-6.17/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-6.17/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..3244421030 --- /dev/null +++ b/queue-6.17/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 719ed511501825a0e23308530129f455fcd58e5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 06c7986131d96..0a7ef770c487c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-6.17/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-6.17/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..41becc6446 --- /dev/null +++ b/queue-6.17/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From 8c487b43dcdc663b052dad233b1c5cf682c963a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index bc24f83339d64..06c7986131d96 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-6.17/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch b/queue-6.17/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch new file mode 100644 index 0000000000..38536f1fef --- /dev/null +++ b/queue-6.17/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch @@ -0,0 +1,53 @@ +From 7450dfe00c4b3f9b2e86950e63ea6698c7f091de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 07:37:34 +0000 +Subject: selftests/bpf: Use ASSERT_STRNEQ to factor in long slab cache names + +From: Matt Bobrowski + +[ Upstream commit d088da904223e8f5e19c6d156cf372d5baec1a7c ] + +subtest_kmem_cache_iter_check_slabinfo() fundamentally compares slab +cache names parsed out from /proc/slabinfo against those stored within +struct kmem_cache_result. The current problem is that the slab cache +name within struct kmem_cache_result is stored within a bounded +fixed-length array (sized to SLAB_NAME_MAX(32)), whereas the name +parsed out from /proc/slabinfo is not. Meaning, using ASSERT_STREQ() +can certainly lead to test failures, particularly when dealing with +slab cache names that are longer than SLAB_NAME_MAX(32) +bytes. Notably, kmem_cache_create() allows callers to create slab +caches with somewhat arbitrarily sized names via its __name identifier +argument, so exceeding the SLAB_NAME_MAX(32) limit that is in place +now can certainly happen. + +Make subtest_kmem_cache_iter_check_slabinfo() more reliable by only +checking up to sizeof(struct kmem_cache_result.name) - 1 using +ASSERT_STRNEQ(). + +Fixes: a496d0cdc84d ("selftests/bpf: Add a test for kmem_cache_iter") +Signed-off-by: Matt Bobrowski +Signed-off-by: Martin KaFai Lau +Acked-by: Song Liu +Link: https://patch.msgid.link/20251118073734.4188710-1-mattbobrowski@google.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +index 1de14b111931a..6e35e13c20220 100644 +--- a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c ++++ b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +@@ -57,7 +57,8 @@ static void subtest_kmem_cache_iter_check_slabinfo(struct kmem_cache_iter *skel) + if (!ASSERT_OK(ret, "kmem_cache_lookup")) + break; + +- ASSERT_STREQ(r.name, name, "kmem_cache_name"); ++ ASSERT_STRNEQ(r.name, name, sizeof(r.name) - 1, ++ "kmem_cache_name"); + ASSERT_EQ(r.obj_size, objsize, "kmem_cache_objsize"); + + seen++; +-- +2.51.0 + diff --git a/queue-6.17/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch b/queue-6.17/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch new file mode 100644 index 0000000000..dd7c50b733 --- /dev/null +++ b/queue-6.17/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch @@ -0,0 +1,198 @@ +From 2524475589819c7a4626a05e98ef93ed2cd3fe76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 18:35:05 -0500 +Subject: selftests/net: packetdrill: pass send_omit_free to MSG_ZEROCOPY tests + +From: Willem de Bruijn + +[ Upstream commit c01a6e5b2e4f21d31cf725b9f3803cb0280b1b8d ] + +The --send_omit_free flag is needed for TCP zero copy tests, to ensure +that packetdrill doesn't free the send() buffer after the send() call. + +Fixes: 1e42f73fd3c2 ("selftests/net: packetdrill: import tcp/zerocopy") +Closes: https://lore.kernel.org/netdev/20251124071831.4cbbf412@kernel.org/ +Suggested-by: Neal Cardwell +Signed-off-by: Willem de Bruijn +Link: https://patch.msgid.link/20251125234029.1320984-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt | 4 ++++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt | 2 ++ + .../selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt | 3 +++ + .../net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt | 3 +++ + .../selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt | 3 +++ + .../net/packetdrill/tcp_zerocopy_fastopen-client.pkt | 2 ++ + .../net/packetdrill/tcp_zerocopy_fastopen-server.pkt | 2 ++ + .../selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt | 2 ++ + 12 files changed, 29 insertions(+) + +diff --git a/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt b/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt +index b2b2cdf27e20f..454441e7ecff6 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt +@@ -1,6 +1,10 @@ + // SPDX-License-Identifier: GPL-2.0 + // Test that we correctly skip zero-length IOVs. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` ++ + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_ZEROCOPY, [1], 4) = 0 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt +index a82c8899d36bf..0a0700afdaa38 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt +@@ -4,6 +4,8 @@ + // send a packet with MSG_ZEROCOPY and receive the notification ID + // repeat and verify IDs are consecutive + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt +index c01915e7f4a15..df91675d2991c 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt +@@ -3,6 +3,8 @@ + // + // send multiple packets, then read one range of all notifications. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt +index 6509882932e91..2963cfcb14dfd 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt +@@ -1,6 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + // Minimal client-side zerocopy test + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt +index 2cd78755cb2ac..ea0c2fa73c2d6 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt +@@ -7,6 +7,8 @@ + // First send on a closed socket and wait for (absent) notification. + // Then connect and send and verify that notification nr. is zero. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt +index 7671c20e01cf6..4df978a9b82e7 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt +@@ -7,6 +7,9 @@ + // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR + // is correctly fired only once, when EPOLLET is set. send another packet with + // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt +index fadc480fdb7fe..36b6edc4858c4 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt +@@ -8,6 +8,9 @@ + // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR + // is correctly fired only once, when EPOLLET is set. send another packet with + // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt +index 5bfa0d1d2f4a3..1bea6f3b4558d 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt +@@ -8,6 +8,9 @@ + // is correctly fired only once, when EPOLLONESHOT is set. send another packet + // with MSG_ZEROCOPY. confirm that EPOLLERR is not fired. Rearm the FD and + // confirm that EPOLLERR is correctly set. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt +index 4a73bbf469610..e27c21ff5d18d 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt +@@ -8,6 +8,8 @@ + // one will have no data in the initial send. On return 0 the + // zerocopy notification counter is not incremented. Verify this too. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + // Send a FastOpen request, no cookie yet so no data in SYN +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt +index 36086c5877ce7..b1fa77c77dfa7 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt +@@ -4,6 +4,8 @@ + // send data with MSG_FASTOPEN | MSG_ZEROCOPY and verify that the + // kernel returns the notification ID. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh + ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x207` + +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt +index 672f817faca0d..2f5317d0a9fab 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt +@@ -7,6 +7,8 @@ + // because each iovec element becomes a frag + // 3) the PSH bit is set on an skb when it runs out of fragments + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt +index a9a1ac0aea4f4..9d5272c6b2079 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt +@@ -4,6 +4,8 @@ + // verify that SO_EE_CODE_ZEROCOPY_COPIED is set on zerocopy + // packets of all sizes, including the smallest payload, 1B. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +-- +2.51.0 + diff --git a/queue-6.17/series b/queue-6.17/series new file mode 100644 index 0000000000..e239a26e64 --- /dev/null +++ b/queue-6.17/series @@ -0,0 +1,434 @@ +smack-deduplicate-does-access-rule-request-transmuta.patch +smack-fix-bug-smack64transmute-set-on-non-directory.patch +smack-deduplicate-xattr-setting-in-smack_inode_init_.patch +smack-always-instantiate-inode-in-smack_inode_init_s.patch +smack-fix-bug-invalid-label-of-unix-socket-file.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +smack-fix-bug-setting-task-label-silently-ignores-in.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch +drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +accel-ivpu-rework-bind-unbind-of-imported-buffers.patch +accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch +accel-ivpu-make-function-parameter-names-consistent.patch +accel-ivpu-fix-dct-active-percent-format.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch +tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch +ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch +pinctrl-renesas-rzg2l-fix-pmc-restore.patch +clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch +clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch +drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch +hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch +remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch +objtool-fix-standalone-hacks-jump_label.patch +objtool-fix-weak-symbol-detection.patch +accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch +perf-parse-events-fix-legacy-cache-events-if-event-i.patch +wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch +wifi-ath11k-restore-register-window-after-global-res.patch +wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch +wifi-ath12k-fix-vht-mcs-assignment.patch +wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch +sched-fair-forfeit-vruntime-on-yield.patch +irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch +irqchip-bcm2712-mip-fix-section-mismatch.patch +irqchip-irq-bcm7038-l1-fix-section-mismatch.patch +irqchip-irq-bcm7120-l2-fix-section-mismatch.patch +irqchip-irq-brcmstb-l2-fix-section-mismatch.patch +irqchip-imx-mu-msi-fix-section-mismatch.patch +irqchip-renesas-rzg2l-fix-section-mismatch.patch +irqchip-starfive-jh8100-fix-section-mismatch.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +crypto-authenc-correctly-pass-einprogress-back-up-to.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +dt-bindings-clock-qcom-x1e80100-gcc-add-missing-usb4.patch +clk-qcom-gcc-x1e80100-add-missing-usb4-clocks-resets.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +inet-avoid-ehash-lookup-race-in-inet_twsk_hashdance_.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch +crypto-aead-fix-reqsize-handling.patch +block-mq-deadline-introduce-dd_start_request.patch +block-mq-deadline-switch-back-to-a-single-dispatch-l.patch +arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch +arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch +perf-annotate-check-return-value-of-evsel__get_arch-.patch +arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch +pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +tty-introduce-tty_port_tty-guard.patch +tty-serial-imx-only-configure-the-wake-register-when.patch +clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch +clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch +clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch +clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch +clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch +clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch +clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch +soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +wifi-ath11k-fix-vht-mcs-assignment.patch +wifi-ath11k-fix-peer-he-mcs-assignment.patch +s390-smp-fix-fallback-cpu-detection.patch +scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +tools-power-turbostat-regression-fix-uncore-mhz-prin.patch +wifi-ath12k-restore-register-window-after-global-res.patch +leds-upboard-fix-module-alias.patch +pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch +arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch +arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch +arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch +arm64-dts-qcom-starqltechn-remove-extra-empty-line.patch +arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch +arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch +arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch +arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch +arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch +arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch +perf-hwmon_pmu-fix-uninitialized-variable-warning.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +arm64-dts-qcom-qcm2290-add-cci-node.patch +arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch +rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch +arm-dts-renesas-gose-remove-superfluous-port-propert.patch +arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch +drm-amdgpu-add-userq-object-va-track-helpers.patch +drm-amdgpu-userq-fix-sdma-and-compute-validation.patch +wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch +revert-mtd-rawnand-marvell-fix-layouts.patch +mtd-nand-relax-ecc-parameter-validation-check.patch +mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch +perf-remove-get_perf_callchain-init_nr-argument.patch +bpf-refactor-stack-map-trace-depth-calculation-into-.patch +bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch +perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch +task_work-fix-nmi-race-condition.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch +media-ov02c10-fix-default-vertical-flip.patch +tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch +tools-nolibc-dirent-avoid-errno-in-readdir_r.patch +clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch +soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +drm-nova-select-nova_core.patch +accel-ivpu-fix-race-condition-when-unbinding-bos.patch +pidfs-add-missing-pidfd_info_size_ver1.patch +pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +random-use-offstack-cpumask-when-necessary.patch +docs-kdoc-fix-duplicate-section-warning-message.patch +wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch +wifi-ath12k-fix-reusing-m3-memory.patch +wifi-ath12k-fix-error-handling-in-creating-hardware-.patch +wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch +interconnect-qcom-msm8996-add-missing-link-to-slave_.patch +arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch +accel-amdxdna-fix-incorrect-command-state-for-timed-.patch +interconnect-debugfs-fix-incorrect-error-handling-fo.patch +arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch +drm-imagination-fix-reference-to-devm_platform_get_a.patch +perf-lock-contention-load-kernel-map-before-lookup.patch +perf-record-skip-synthesize-event-when-open-evsel-fa.patch +timers-migration-convert-while-loops-to-use-for.patch +timers-migration-remove-locking-on-group-connection.patch +timers-migration-fix-imbalanced-numa-trees.patch +power-supply-rt5033_charger-fix-device-node-referenc.patch +power-supply-cw2015-check-devm_delayed_work_autocanc.patch +power-supply-max17040-check-iio_read_channel_process.patch +power-supply-rt9467-return-error-on-failure-in-rt946.patch +power-supply-rt9467-prevent-using-uninitialized-loca.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +scsi-target-fix-lun-device-r-w-and-total-command-sta.patch +fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch +drm-panthor-handle-errors-returned-by-drm_sched_enti.patch +drm-panthor-fix-group_free_queue-for-partially-initi.patch +drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch +drm-panthor-fix-race-with-suspend-during-unplug.patch +drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch +firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch +iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch +cleanup-fix-scoped_class.patch +spi-tegra210-quad-fix-timeout-handling.patch +libbpf-fix-parsing-of-multi-split-btf.patch +arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch +arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch +arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch +entry-unwind-deferred-fix-unwind_reset_info-placemen.patch +coresight-etr-fix-etr-buffer-use-after-free-issue.patch +x86-boot-fix-page-table-access-in-5-level-to-4-level.patch +efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch +locktorture-fix-memory-leak-in-param_set_cpumask.patch +wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch +wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch +io_uring-use-write_once-for-user-shared-memory.patch +perf-x86-fix-null-event-access-and-potential-pebs-re.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch +md-fix-rcu-protection-in-md_wakeup_thread.patch +md-avoid-repeated-calls-to-del_gendisk.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +scsi-smartpqi-fix-device-resources-accessed-after-de.patch +staging-most-remove-broken-i2c-driver.patch +iio-imu-bmi270-fix-dev_err_probe-error-msg.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch +coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch +ntfs3-init-run-lock-for-extend-inode.patch +drm-panthor-fix-potential-memleak-of-vma-structure.patch +scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch +md-delete-md_redundancy_group-when-array-is-becoming.patch +cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch +powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +coresight-change-device-mode-to-atomic-type.patch +coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch +coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch +coresight-etm4x-correct-polling-idle-bit.patch +coresight-etm4x-add-context-synchronization-before-e.patch +coresight-etm4x-properly-control-filter-in-cpu-idle-.patch +perf-tools-fix-missing-feature-check-for-inherit-sam.patch +drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch +drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch +clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +accel-amdxdna-clear-mailbox-interrupt-register-durin.patch +accel-amdxdna-fix-deadlock-between-context-destroy-a.patch +bpf-free-special-fields-when-update-lru_-percpu_hash.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12003 +crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch +s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch +arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch +drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +pci-prevent-resource-tree-corruption-when-bar-resize.patch +bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch +bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch +mshv-fix-deposit-memory-in-mshv_root_hvcall.patch +drivers-hv-vmbus-protocol-version-6.0.patch +drivers-hv-allocate-encrypted-buffers-when-requested.patch +drivers-hv-free-msginfo-when-the-buffer-fails-to-dec.patch +mshv-fix-create-memory-region-overlap-check.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +watchdog-starfive-fix-resource-leak-in-probe-error-p.patch +fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch +tracefs-fix-a-leak-in-eventfs_create_events_dir.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch +arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch +block-blk-throttle-fix-throttle-slice-time-for-ssds.patch +drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch +drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch +drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch +net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch +bpf-fix-invalid-prog-stats-access-when-update_effect.patch +powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch +drm-msm-a6xx-fix-the-gemnoc-workaround.patch +drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch +spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch +ipv6-clear-ra-flags-when-adding-a-static-route.patch +perf-arm_spe-fix-memset-subclass-in-operation.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch +scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch +net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch +iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch +wifi-mac80211-fix-cmac-functions-not-handling-errors.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +of-fdt-consolidate-duplicate-code-into-helper-functi.patch +of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch +leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch +phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch +phy-rockchip-naneng-combphy-add-soc-prefix-to-regist.patch +phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch +phy-freescale-initialize-priv-lock.patch +phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch +phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch +phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch +asoc-sdca-fix-missing-dash-in-hide-disco-property.patch +selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch +net-phy-adin1100-fix-software-power-down-ready-condi.patch +cpuset-treat-cpusets-in-attaching-as-populated.patch +clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ras-report-all-arm-processor-cper-information-to-use.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +regulator-pca9450-fix-error-code-in-probe.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-starfive-correctly-handle-return-of-sg_nents_.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch +risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch +erofs-correct-fsdax-detection.patch +erofs-limit-the-level-of-fs-stacking-for-file-backed.patch +rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch +rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch +crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch +crypto-ahash-zero-positive-err-value-in-ahash_update.patch +asoc-tas2781-correct-the-wrong-period.patch +wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch +wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch +wifi-mt76-mt7925-add-mbssid-support.patch +wifi-mt76-mt7921-add-mbssid-support.patch +revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch +wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch +wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch +wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch +wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch +wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch +wifi-mt76-mt7996-fix-mld-group-index-assignment.patch +wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch +wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch +wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch +wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch +btrfs-fix-double-free-of-qgroup-record-after-failure.patch +btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch +btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch +um-don-t-rename-vmap-to-kernel_vmap.patch +iomap-always-run-error-completions-in-user-context.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch +drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch +clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch +clocksource-drivers-stm-fix-double-deregistration-on.patch +clocksource-drivers-nxp-stm-fix-section-mismatches.patch +clocksource-drivers-nxp-stm-prevent-driver-unbind.patch +asoc-nau8325-use-simple-i2c-probe-function.patch +asoc-nau8325-add-missing-build-config.patch +gfs2-prevent-recursive-memory-reclaim.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +firmware_loader-make-rust_fw_loader_abstractions-sel.patch +greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch +misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch +kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ublk-prevent-invalid-access-with-debug.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +selftests-net-packetdrill-pass-send_omit_free-to-msg.patch +of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-typo-in-virtio_device_ready-comment.patch +virtio-fix-whitespace-in-virtio_config_ops.patch +virtio-fix-grammar-in-virtio_queue_info-docs.patch +virtio-fix-virtqueue_set_affinity-docs.patch +vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch +vhost-fix-kthread-worker-cgroup-failure-handling.patch +vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch +virtio-clean-up-features-qword-dword-terms.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch +arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch +arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +reinstate-resource-avoid-unnecessary-lookups-in-find.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +iavf-implement-settime64-with-eopnotsupp.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch +spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch +vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch +net-phy-aquantia-check-for-nvmem-deferral.patch +selftests-bonding-add-delay-before-each-xvlan_over_b.patch +net-netpoll-initialize-work-queue-before-error-check.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch +rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch +clk-keystone-fix-compile-testing.patch +net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch +net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch +net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch +net-dsa-b53-move-reading-arl-entries-into-their-own-.patch +net-dsa-b53-move-writing-arl-entries-into-their-own-.patch +net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch +net-dsa-b53-split-reading-search-entry-into-their-ow.patch +net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch +net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch +net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch +net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch +net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch +net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch +net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch +net-hsr-create-an-api-to-get-hsr-port-type.patch +net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-jitdump-add-sym-str-tables-to-build-id-generati.patch +perf-tools-mark-split-kallsyms-dsos-as-loaded.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch +9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch +sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch +sched-core-fix-psi_dequeue-for-proxy-execution.patch diff --git a/queue-6.17/smack-always-instantiate-inode-in-smack_inode_init_s.patch b/queue-6.17/smack-always-instantiate-inode-in-smack_inode_init_s.patch new file mode 100644 index 0000000000..3f5b95be93 --- /dev/null +++ b/queue-6.17/smack-always-instantiate-inode-in-smack_inode_init_s.patch @@ -0,0 +1,70 @@ +From 7727bf07ac0e22871b08a5daba6e897343fd8c2e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:31 +0300 +Subject: smack: always "instantiate" inode in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 69204f6cdb90f56b7ca27966d1080841108fc5de ] + +If memory allocation for the SMACK64TRANSMUTE +xattr value fails in smack_inode_init_security(), +the SMK_INODE_INSTANT flag is not set in +(struct inode_smack *issp)->smk_flags, +leaving the inode as not "instantiated". + +It does not matter if fs frees the inode +after failed smack_inode_init_security() call, +but there is no guarantee for this. + +To be safe, mark the inode as "instantiated", +even if allocation of xattr values fails. + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 8609ae26e365e..5cd19f3498cbd 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1015,6 +1015,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); ++ int rc = 0; ++ int transflag = 0; + bool trans_cred; + bool trans_rule; + +@@ -1043,18 +1045,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_inode = dsp; + + if (S_ISDIR(inode->i_mode)) { +- issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ transflag = SMK_INODE_TRANSMUTE; + + if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_TRANSMUTE, + TRANS_TRUE, + TRANS_TRUE_SIZE + )) +- return -ENOMEM; ++ rc = -ENOMEM; + } + } + +- issp->smk_flags |= SMK_INODE_INSTANT; ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ if (rc) ++ return rc; + + return xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, +-- +2.51.0 + diff --git a/queue-6.17/smack-deduplicate-does-access-rule-request-transmuta.patch b/queue-6.17/smack-deduplicate-does-access-rule-request-transmuta.patch new file mode 100644 index 0000000000..cb8ad17ecf --- /dev/null +++ b/queue-6.17/smack-deduplicate-does-access-rule-request-transmuta.patch @@ -0,0 +1,145 @@ +From 86e48d6c33ed2d839ad5a5478049bcf5ccb6c060 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:28 +0300 +Subject: smack: deduplicate "does access rule request transmutation" + +From: Konstantin Andreev + +[ Upstream commit 635a01da8385fc00a144ec24684100bd1aa9db11 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 57 +++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 25 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index fc340a6f0ddea..8629e58ea4fa1 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -962,6 +962,24 @@ static int smack_inode_alloc_security(struct inode *inode) + return 0; + } + ++/** ++ * smk_rule_transmutes - does access rule for (subject,object) contain 't'? ++ * @subject: a pointer to the subject's Smack label entry ++ * @object: a pointer to the object's Smack label entry ++ */ ++static bool ++smk_rule_transmutes(struct smack_known *subject, ++ const struct smack_known *object) ++{ ++ int may; ++ ++ rcu_read_lock(); ++ may = smk_access_entry(subject->smk_known, object->smk_known, ++ &subject->smk_rules); ++ rcu_read_unlock(); ++ return (may > 0) && (may & MAY_TRANSMUTE); ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -977,23 +995,19 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct xattr *xattrs, int *xattr_count) + { + struct task_smack *tsp = smack_cred(current_cred()); +- struct inode_smack *issp = smack_inode(inode); +- struct smack_known *skp = smk_of_task(tsp); +- struct smack_known *isp = smk_of_inode(inode); ++ struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); + struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); +- int may; ++ bool trans_cred; ++ bool trans_rule; + + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. + */ +- if (tsp->smk_task != tsp->smk_transmuted) { +- rcu_read_lock(); +- may = smk_access_entry(skp->smk_known, dsp->smk_known, +- &skp->smk_rules); +- rcu_read_unlock(); +- } ++ trans_cred = (tsp->smk_task == tsp->smk_transmuted); ++ if (!trans_cred) ++ trans_rule = smk_rule_transmutes(smk_of_task(tsp), dsp); + + /* + * In addition to having smk_task equal to smk_transmuted, +@@ -1001,9 +1015,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * requests transmutation then by all means transmute. + * Mark the inode as changed. + */ +- if ((tsp->smk_task == tsp->smk_transmuted) || +- (may > 0 && ((may & MAY_TRANSMUTE) != 0) && +- smk_inode_transmutable(dir))) { ++ if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { + struct xattr *xattr_transmute; + + /* +@@ -1012,8 +1024,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * inode label was already set correctly in + * smack_inode_alloc_security(). + */ +- if (tsp->smk_task != tsp->smk_transmuted) +- isp = issp->smk_inode = dsp; ++ if (!trans_cred) ++ issp->smk_inode = dsp; + + issp->smk_flags |= SMK_INODE_TRANSMUTE; + xattr_transmute = lsm_get_xattr_slot(xattrs, +@@ -1033,11 +1045,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_flags |= SMK_INODE_INSTANT; + + if (xattr) { +- xattr->value = kstrdup(isp->smk_known, GFP_NOFS); ++ const char *inode_label = issp->smk_inode->smk_known; ++ ++ xattr->value = kstrdup(inode_label, GFP_NOFS); + if (!xattr->value) + return -ENOMEM; + +- xattr->value_len = strlen(isp->smk_known); ++ xattr->value_len = strlen(inode_label); + xattr->name = XATTR_SMACK_SUFFIX; + } + +@@ -4915,7 +4929,6 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + struct task_smack *otsp = smack_cred(old); + struct task_smack *ntsp = smack_cred(new); + struct inode_smack *isp; +- int may; + + /* + * Use the process credential unless all of +@@ -4929,18 +4942,12 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + isp = smack_inode(d_inode(dentry->d_parent)); + + if (isp->smk_flags & SMK_INODE_TRANSMUTE) { +- rcu_read_lock(); +- may = smk_access_entry(otsp->smk_task->smk_known, +- isp->smk_inode->smk_known, +- &otsp->smk_task->smk_rules); +- rcu_read_unlock(); +- + /* + * If the directory is transmuting and the rule + * providing access is transmuting use the containing + * directory label instead of the process label. + */ +- if (may > 0 && (may & MAY_TRANSMUTE)) { ++ if (smk_rule_transmutes(otsp->smk_task, isp->smk_inode)) { + ntsp->smk_task = isp->smk_inode; + ntsp->smk_transmuted = ntsp->smk_task; + } +-- +2.51.0 + diff --git a/queue-6.17/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch b/queue-6.17/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch new file mode 100644 index 0000000000..a4c638d9fa --- /dev/null +++ b/queue-6.17/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch @@ -0,0 +1,113 @@ +From 9deecc8241b47e3a453c0cde201156082d97442f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:30 +0300 +Subject: smack: deduplicate xattr setting in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 8e5d9f916a9678e2dcbed2289b87efd453e4e052 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 56 ++++++++++++++++++++------------------ + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d6f814aa15bae..8609ae26e365e 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -980,6 +980,24 @@ smk_rule_transmutes(struct smack_known *subject, + return (may > 0) && (may & MAY_TRANSMUTE); + } + ++static int ++xattr_dupval(struct xattr *xattrs, int *xattr_count, ++ const char *name, const void *value, unsigned int vallen) ++{ ++ struct xattr * const xattr = lsm_get_xattr_slot(xattrs, xattr_count); ++ ++ if (!xattr) ++ return 0; ++ ++ xattr->value = kmemdup(value, vallen, GFP_NOFS); ++ if (!xattr->value) ++ return -ENOMEM; ++ ++ xattr->value_len = vallen; ++ xattr->name = name; ++ return 0; ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -997,7 +1015,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); +- struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); + bool trans_cred; + bool trans_rule; + +@@ -1016,8 +1033,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * Mark the inode as changed. + */ + if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { +- struct xattr *xattr_transmute; +- + /* + * The caller of smack_dentry_create_files_as() + * should have overridden the current cred, so the +@@ -1029,35 +1044,22 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + + if (S_ISDIR(inode->i_mode)) { + issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; +- } ++ ++ if (xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_TRANSMUTE, ++ TRANS_TRUE, ++ TRANS_TRUE_SIZE ++ )) ++ return -ENOMEM; + } + } + + issp->smk_flags |= SMK_INODE_INSTANT; + +- if (xattr) { +- const char *inode_label = issp->smk_inode->smk_known; +- +- xattr->value = kstrdup(inode_label, GFP_NOFS); +- if (!xattr->value) +- return -ENOMEM; +- +- xattr->value_len = strlen(inode_label); +- xattr->name = XATTR_SMACK_SUFFIX; +- } +- +- return 0; ++ return xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_SUFFIX, ++ issp->smk_inode->smk_known, ++ strlen(issp->smk_inode->smk_known)); + } + + /** +-- +2.51.0 + diff --git a/queue-6.17/smack-fix-bug-invalid-label-of-unix-socket-file.patch b/queue-6.17/smack-fix-bug-invalid-label-of-unix-socket-file.patch new file mode 100644 index 0000000000..8a46b093b7 --- /dev/null +++ b/queue-6.17/smack-fix-bug-invalid-label-of-unix-socket-file.patch @@ -0,0 +1,200 @@ +From f15aa9d16507c4eaceec454c591a0ea6226f9c97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:32 +0300 +Subject: smack: fix bug: invalid label of unix socket file + +From: Konstantin Andreev + +[ Upstream commit 78fc6a94be252b27bb73e4926eed70b5e302a8e0 ] + +According to [1], the label of a UNIX domain socket (UDS) +file (i.e., the filesystem object representing the socket) +is not supposed to participate in Smack security. + +To achieve this, [1] labels UDS files with "*" +in smack_d_instantiate(). + +Before [2], smack_d_instantiate() was responsible +for initializing Smack security for all inodes, +except ones under /proc + +[2] imposed the sole responsibility for initializing +inode security for newly created filesystem objects +on smack_inode_init_security(). + +However, smack_inode_init_security() lacks some logic +present in smack_d_instantiate(). +In particular, it does not label UDS files with "*". + +This patch adds the missing labeling of UDS files +with "*" to smack_inode_init_security(). + +Labeling UDS files with "*" in smack_d_instantiate() +still works for stale UDS files that already exist on +disk. Stale UDS files are useless, but I keep labeling +them for consistency and maybe to make easier for user +to delete them. + +Compared to [1], this version introduces the following +improvements: + + * UDS file label is held inside inode only + and not saved to xattrs. + + * relabeling UDS files (setxattr, removexattr, etc.) + is blocked. + +[1] 2010-11-24 Casey Schaufler +commit b4e0d5f0791b ("Smack: UDS revision") + +[2] 2023-11-16 roberto.sassu +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 5 +++ + security/smack/smack_lsm.c | 58 +++++++++++++++++++------ + 2 files changed, 49 insertions(+), 14 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 6d44f4fdbf59f..1b554b5bf98e6 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -696,6 +696,11 @@ sockets. + A privileged program may set this to match the label of another + task with which it hopes to communicate. + ++UNIX domain socket (UDS) with a BSD address functions both as a file in a ++filesystem and as a socket. As a file, it carries the SMACK64 attribute. This ++attribute is not involved in Smack security enforcement and is immutably ++assigned the label "*". ++ + Smack Netlabel Exceptions + ~~~~~~~~~~~~~~~~~~~~~~~~~ + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 5cd19f3498cbd..30f20fef3331e 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1020,6 +1020,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + bool trans_cred; + bool trans_rule; + ++ /* ++ * UNIX domain sockets use lower level socket data. Let ++ * UDS inode have fixed * label to keep smack_inode_permission() calm ++ * when called from unix_find_bsd() ++ */ ++ if (S_ISSOCK(inode->i_mode)) { ++ /* forced label, no need to save to xattrs */ ++ issp->smk_inode = &smack_known_star; ++ goto instant_inode; ++ } + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. +@@ -1056,14 +1066,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + } + } + +- issp->smk_flags |= (SMK_INODE_INSTANT | transflag); +- if (rc) +- return rc; +- +- return xattr_dupval(xattrs, xattr_count, ++ if (rc == 0) ++ if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, + issp->smk_inode->smk_known, +- strlen(issp->smk_inode->smk_known)); ++ strlen(issp->smk_inode->smk_known) ++ )) ++ rc = -ENOMEM; ++instant_inode: ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ return rc; + } + + /** +@@ -1337,13 +1349,23 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + int check_import = 0; + int check_star = 0; + int rc = 0; ++ umode_t const i_mode = d_backing_inode(dentry)->i_mode; + + /* + * Check label validity here so import won't fail in post_setxattr + */ +- if (strcmp(name, XATTR_NAME_SMACK) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { ++ if (strcmp(name, XATTR_NAME_SMACK) == 0) { ++ /* ++ * UDS inode has fixed label ++ */ ++ if (S_ISSOCK(i_mode)) { ++ rc = -EINVAL; ++ } else { ++ check_priv = 1; ++ check_import = 1; ++ } ++ } else if (strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || ++ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + check_priv = 1; + check_import = 1; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || +@@ -1353,7 +1375,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + check_star = 1; + } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { + check_priv = 1; +- if (!S_ISDIR(d_backing_inode(dentry)->i_mode) || ++ if (!S_ISDIR(i_mode) || + size != TRANS_TRUE_SIZE || + strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) + rc = -EINVAL; +@@ -1484,12 +1506,15 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap, + * Don't do anything special for these. + * XATTR_NAME_SMACKIPIN + * XATTR_NAME_SMACKIPOUT ++ * XATTR_NAME_SMACK if S_ISSOCK (UDS inode has fixed label) + */ + if (strcmp(name, XATTR_NAME_SMACK) == 0) { +- struct super_block *sbp = dentry->d_sb; +- struct superblock_smack *sbsp = smack_superblock(sbp); ++ if (!S_ISSOCK(d_backing_inode(dentry)->i_mode)) { ++ struct super_block *sbp = dentry->d_sb; ++ struct superblock_smack *sbsp = smack_superblock(sbp); + +- isp->smk_inode = sbsp->smk_default; ++ isp->smk_inode = sbsp->smk_default; ++ } + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) + isp->smk_task = NULL; + else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) +@@ -3607,7 +3632,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + + /* +- * UNIX domain sockets use lower level socket data. ++ * UDS inode has fixed label (*) + */ + if (S_ISSOCK(inode->i_mode)) { + final = &smack_known_star; +@@ -4872,6 +4897,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) + + static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) + { ++ /* ++ * UDS inode has fixed label. Ignore nfs label. ++ */ ++ if (S_ISSOCK(inode->i_mode)) ++ return 0; + return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, + ctxlen, 0); + } +-- +2.51.0 + diff --git a/queue-6.17/smack-fix-bug-setting-task-label-silently-ignores-in.patch b/queue-6.17/smack-fix-bug-setting-task-label-silently-ignores-in.patch new file mode 100644 index 0000000000..107a9cdf87 --- /dev/null +++ b/queue-6.17/smack-fix-bug-setting-task-label-silently-ignores-in.patch @@ -0,0 +1,463 @@ +From de7dea44d6dd2623ca2168c42989777203e0ff32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:17 +0300 +Subject: smack: fix bug: setting task label silently ignores input garbage + +From: Konstantin Andreev + +[ Upstream commit 674e2b24791cbe8fd5dc8a0aed4cb4404fcd2028 ] + +This command: + # echo foo/bar >/proc/$$/attr/smack/current + +gives the task a label 'foo' w/o indication +that label does not match input. +Setting the label with lsm_set_self_attr() syscall +behaves identically. + +This occures because: + +1) smk_parse_smack() is used to convert input to a label +2) smk_parse_smack() takes only that part from the + beginning of the input that looks like a label. +3) `/' is prohibited in labels, so only "foo" is taken. + +(2) is by design, because smk_parse_smack() is used +for parsing strings which are more than just a label. + +Silent failure is not a good thing, and there are two +indicators that this was not done intentionally: + + (size >= SMK_LONGLABEL) ~> invalid + +clause at the beginning of the do_setattr() and the +"Returns the length of the smack label" claim +in the do_setattr() description. + +So I fixed this by adding one tiny check: +the taken label length == input length. + +Since input length is now strictly controlled, +I changed the two ways of setting label + + smack_setselfattr(): lsm_set_self_attr() syscall + smack_setprocattr(): > /proc/.../current + +to accommodate the divergence in +what they understand by "input length": + + smack_setselfattr counts mandatory \0 into input length, + smack_setprocattr does not. + + smack_setprocattr allows various trailers after label + +Related changes: + +* fixed description for smk_parse_smack + +* allow unprivileged tasks validate label syntax. + +* extract smk_parse_label_len() from smk_parse_smack() + so parsing may be done w/o string allocation. + +* extract smk_import_valid_label() from smk_import_entry() + to avoid repeated parsing. + +* smk_parse_smack(): scan null-terminated strings + for no more than SMK_LONGLABEL(256) characters + +* smack_setselfattr(): require struct lsm_ctx . flags == 0 + to reserve them for future. + +Fixes: e114e473771c ("Smack: Simplified Mandatory Access Control Kernel") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 11 ++- + security/smack/smack.h | 3 + + security/smack/smack_access.c | 93 ++++++++++++++----- + security/smack/smack_lsm.c | 115 +++++++++++++++--------- + 4 files changed, 156 insertions(+), 66 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 1b554b5bf98e6..c5ed775f2d107 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -601,10 +601,15 @@ specification. + Task Attribute + ~~~~~~~~~~~~~~ + +-The Smack label of a process can be read from /proc//attr/current. A +-process can read its own Smack label from /proc/self/attr/current. A ++The Smack label of a process can be read from ``/proc//attr/current``. A ++process can read its own Smack label from ``/proc/self/attr/current``. A + privileged process can change its own Smack label by writing to +-/proc/self/attr/current but not the label of another process. ++``/proc/self/attr/current`` but not the label of another process. ++ ++Format of writing is : only the label or the label followed by one of the ++3 trailers: ``\n`` (by common agreement for ``/proc/...`` interfaces), ++``\0`` (because some applications incorrectly include it), ++``\n\0`` (because we think some applications may incorrectly include it). + + File Attribute + ~~~~~~~~~~~~~~ +diff --git a/security/smack/smack.h b/security/smack/smack.h +index bf6a6ed3946ce..759343a6bbaeb 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -286,9 +286,12 @@ int smk_tskacc(struct task_smack *, struct smack_known *, + int smk_curacc(struct smack_known *, u32, struct smk_audit_info *); + int smack_str_from_perm(char *string, int access); + struct smack_known *smack_from_secid(const u32); ++int smk_parse_label_len(const char *string, int len); + char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); + struct smack_known *smk_import_entry(const char *, int); ++struct smack_known *smk_import_valid_label(const char *label, int label_len, ++ gfp_t gfp); + void smk_insert_entry(struct smack_known *skp); + struct smack_known *smk_find_entry(const char *); + bool smack_privileged(int cap); +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 2e4a0cb22782b..a289cb6672bd4 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -443,19 +443,19 @@ struct smack_known *smk_find_entry(const char *string) + } + + /** +- * smk_parse_smack - parse smack label from a text string +- * @string: a text string that might contain a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_parse_label_len - calculate the length of the starting segment ++ * in the string that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated + * +- * Returns a pointer to the clean label or an error code. ++ * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code. + */ +-char *smk_parse_smack(const char *string, int len) ++int smk_parse_label_len(const char *string, int len) + { +- char *smack; + int i; + +- if (len <= 0) +- len = strlen(string) + 1; ++ if (len <= 0 || len > SMK_LONGLABEL) ++ len = SMK_LONGLABEL; + + /* + * Reserve a leading '-' as an indicator that +@@ -463,7 +463,7 @@ char *smk_parse_smack(const char *string, int len) + * including /smack/cipso and /smack/cipso2 + */ + if (string[0] == '-') +- return ERR_PTR(-EINVAL); ++ return -EINVAL; + + for (i = 0; i < len; i++) + if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || +@@ -471,6 +471,25 @@ char *smk_parse_smack(const char *string, int len) + break; + + if (i == 0 || i >= SMK_LONGLABEL) ++ return -EINVAL; ++ ++ return i; ++} ++ ++/** ++ * smk_parse_smack - copy the starting segment in the string ++ * that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the copy of the label or an error code. ++ */ ++char *smk_parse_smack(const char *string, int len) ++{ ++ char *smack; ++ int i = smk_parse_label_len(string, len); ++ ++ if (i < 0) + return ERR_PTR(-EINVAL); + + smack = kstrndup(string, i, GFP_NOFS); +@@ -554,31 +573,25 @@ int smack_populate_secattr(struct smack_known *skp) + } + + /** +- * smk_import_entry - import a label, return the list entry +- * @string: a text string that might be a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_import_valid_allocated_label - import a label, return the list entry ++ * @smack: a text string that is a valid Smack label and may be kfree()ed. ++ * It is consumed: either becomes a part of the entry or kfree'ed. + * +- * Returns a pointer to the entry in the label list that +- * matches the passed string, adding it if necessary, +- * or an error code. ++ * Returns: see description of smk_import_entry() + */ +-struct smack_known *smk_import_entry(const char *string, int len) ++static struct smack_known * ++smk_import_allocated_label(char *smack, gfp_t gfp) + { + struct smack_known *skp; +- char *smack; + int rc; + +- smack = smk_parse_smack(string, len); +- if (IS_ERR(smack)) +- return ERR_CAST(smack); +- + mutex_lock(&smack_known_lock); + + skp = smk_find_entry(smack); + if (skp != NULL) + goto freeout; + +- skp = kzalloc(sizeof(*skp), GFP_NOFS); ++ skp = kzalloc(sizeof(*skp), gfp); + if (skp == NULL) { + skp = ERR_PTR(-ENOMEM); + goto freeout; +@@ -608,6 +621,42 @@ struct smack_known *smk_import_entry(const char *string, int len) + return skp; + } + ++/** ++ * smk_import_entry - import a label, return the list entry ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the entry in the label list that ++ * matches the passed string, adding it if necessary, ++ * or an error code. ++ */ ++struct smack_known *smk_import_entry(const char *string, int len) ++{ ++ char *smack = smk_parse_smack(string, len); ++ ++ if (IS_ERR(smack)) ++ return ERR_CAST(smack); ++ ++ return smk_import_allocated_label(smack, GFP_NOFS); ++} ++ ++/** ++ * smk_import_valid_label - import a label, return the list entry ++ * @label a text string that is a valid Smack label, not null-terminated ++ * ++ * Returns: see description of smk_import_entry() ++ */ ++struct smack_known * ++smk_import_valid_label(const char *label, int label_len, gfp_t gfp) ++{ ++ char *smack = kstrndup(label, label_len, gfp); ++ ++ if (!smack) ++ return ERR_PTR(-ENOMEM); ++ ++ return smk_import_allocated_label(smack, gfp); ++} ++ + /** + * smack_from_secid - find the Smack label associated with a secid + * @secid: an integer that might be associated with a Smack label +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 159ccc1d9847c..adf1c542d2134 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3710,7 +3710,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * @attr: which attribute to fetch + * @ctx: buffer to receive the result + * @size: available size in, actual size out +- * @flags: unused ++ * @flags: reserved, currently zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3771,57 +3771,52 @@ static int smack_getprocattr(struct task_struct *p, const char *name, char **val + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns zero on success or an error code + */ +-static int do_setattr(u64 attr, void *value, size_t size) ++static int do_setattr(unsigned int attr, void *value, size_t size) + { + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- char *labelstr; +- int rc = 0; +- +- if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) +- return -EPERM; ++ int label_len; + ++ /* ++ * let unprivileged user validate input, check permissions later ++ */ + if (value == NULL || size == 0 || size >= SMK_LONGLABEL) + return -EINVAL; + +- if (attr != LSM_ATTR_CURRENT) +- return -EOPNOTSUPP; +- +- labelstr = smk_parse_smack(value, size); +- if (IS_ERR(labelstr)) +- return PTR_ERR(labelstr); ++ label_len = smk_parse_label_len(value, size); ++ if (label_len < 0 || label_len != size) ++ return -EINVAL; + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (labelstr[1] == '\0' /* '@', '*' */) { +- const char c = labelstr[0]; ++ if (label_len == 1 /* '@', '*' */) { ++ const char c = *(const char *)value; + + if (c == *smack_known_web.smk_known || +- c == *smack_known_star.smk_known) { +- rc = -EPERM; +- goto free_labelstr; +- } ++ c == *smack_known_star.smk_known) ++ return -EPERM; + } + + if (!smack_privileged(CAP_MAC_ADMIN)) { + const struct smack_known_list_elem *sklep; +- list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) +- goto free_labelstr; +- rc = -EPERM; +- } ++ list_for_each_entry(sklep, &tsp->smk_relabel, list) { ++ const char *cp = sklep->smk_label->smk_known; + +-free_labelstr: +- kfree(labelstr); +- if (rc) ++ if (strlen(cp) == label_len && ++ strncmp(cp, value, label_len) == 0) ++ goto in_relabel; ++ } + return -EPERM; ++in_relabel: ++ ; ++ } + +- skp = smk_import_entry(value, size); ++ skp = smk_import_valid_label(value, label_len, GFP_KERNEL); + if (IS_ERR(skp)) + return PTR_ERR(skp); + +@@ -3837,7 +3832,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + smk_destroy_label_list(&tsp->smk_relabel); + + commit_creds(new); +- return size; ++ return 0; + } + + /** +@@ -3845,7 +3840,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + * @attr: which attribute to set + * @ctx: buffer containing the data + * @size: size of @ctx +- * @flags: unused ++ * @flags: reserved, must be zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3855,12 +3850,26 @@ static int do_setattr(u64 attr, void *value, size_t size) + static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + u32 size, u32 flags) + { +- int rc; ++ if (attr != LSM_ATTR_CURRENT) ++ return -EOPNOTSUPP; + +- rc = do_setattr(attr, ctx->ctx, ctx->ctx_len); +- if (rc > 0) +- return 0; +- return rc; ++ if (ctx->flags) ++ return -EINVAL; ++ /* ++ * string must have \0 terminator, included in ctx->ctx ++ * (see description of struct lsm_ctx) ++ */ ++ if (ctx->ctx_len == 0) ++ return -EINVAL; ++ ++ if (ctx->ctx[ctx->ctx_len - 1] != '\0') ++ return -EINVAL; ++ /* ++ * other do_setattr() caller, smack_setprocattr(), ++ * does not count \0 into size, so ++ * decreasing length by 1 to accommodate the divergence. ++ */ ++ return do_setattr(attr, ctx->ctx, ctx->ctx_len - 1); + } + + /** +@@ -3872,15 +3881,39 @@ static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns the size of the input value or an error code + */ + static int smack_setprocattr(const char *name, void *value, size_t size) + { +- int attr = lsm_name_to_attr(name); ++ size_t realsize = size; ++ unsigned int attr = lsm_name_to_attr(name); + +- if (attr != LSM_ATTR_UNDEF) +- return do_setattr(attr, value, size); +- return -EINVAL; ++ switch (attr) { ++ case LSM_ATTR_UNDEF: return -EINVAL; ++ default: return -EOPNOTSUPP; ++ case LSM_ATTR_CURRENT: ++ ; ++ } ++ ++ /* ++ * The value for the "current" attribute is the label ++ * followed by one of the 4 trailers: none, \0, \n, \n\0 ++ * ++ * I.e. following inputs are accepted as 3-characters long label "foo": ++ * ++ * "foo" (3 characters) ++ * "foo\0" (4 characters) ++ * "foo\n" (4 characters) ++ * "foo\n\0" (5 characters) ++ */ ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\0')) ++ --realsize; ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\n')) ++ --realsize; ++ ++ return do_setattr(attr, value, realsize) ? : size; + } + + /** +-- +2.51.0 + diff --git a/queue-6.17/smack-fix-bug-smack64transmute-set-on-non-directory.patch b/queue-6.17/smack-fix-bug-smack64transmute-set-on-non-directory.patch new file mode 100644 index 0000000000..9f85e4dca6 --- /dev/null +++ b/queue-6.17/smack-fix-bug-smack64transmute-set-on-non-directory.patch @@ -0,0 +1,82 @@ +From 9a275e5bea03e067e920366a423475c59bfc198b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:29 +0300 +Subject: smack: fix bug: SMACK64TRANSMUTE set on non-directory + +From: Konstantin Andreev + +[ Upstream commit 195da3ff244deff119c3f5244b464b2236ea1725 ] + +When a new file system object is created +and the conditions for label transmutation are met, +the SMACK64TRANSMUTE extended attribute is set +on the object regardless of its type: +file, pipe, socket, symlink, or directory. + +However, +SMACK64TRANSMUTE may only be set on directories. + +This bug is a combined effect of the commits [1] and [2] +which both transfer functionality +from smack_d_instantiate() to smack_inode_init_security(), +but only in part. + +Commit [1] set blank SMACK64TRANSMUTE on improper object types. +Commit [2] set "TRUE" SMACK64TRANSMUTE on improper object types. + +[1] 2023-06-10, +Fixes: baed456a6a2f ("smack: Set the SMACK64TRANSMUTE xattr in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20230610075738.3273764-3-roberto.sassu@huaweicloud.com/ + +[2] 2023-11-16, +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 8629e58ea4fa1..d6f814aa15bae 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1027,18 +1027,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + if (!trans_cred) + issp->smk_inode = dsp; + +- issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ if (S_ISDIR(inode->i_mode)) { ++ issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ xattr_transmute = lsm_get_xattr_slot(xattrs, ++ xattr_count); ++ if (xattr_transmute) { ++ xattr_transmute->value = kmemdup(TRANS_TRUE, ++ TRANS_TRUE_SIZE, ++ GFP_NOFS); ++ if (!xattr_transmute->value) ++ return -ENOMEM; ++ ++ xattr_transmute->value_len = TRANS_TRUE_SIZE; ++ xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ } + } + } + +-- +2.51.0 + diff --git a/queue-6.17/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-6.17/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..8074426344 --- /dev/null +++ b/queue-6.17/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From 613d0276f946d9a7c8595a48a38d518712458aa9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 30f20fef3331e..159ccc1d9847c 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3778,8 +3778,8 @@ static int do_setattr(u64 attr, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3790,28 +3790,41 @@ static int do_setattr(u64 attr, void *value, size_t size) + if (attr != LSM_ATTR_CURRENT) + return -EOPNOTSUPP; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.17/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch b/queue-6.17/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch new file mode 100644 index 0000000000..49206f8746 --- /dev/null +++ b/queue-6.17/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch @@ -0,0 +1,60 @@ +From ef5cc4de843564f2c53ee98d69ad2d2fcfdaf15e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 00:02:15 +0800 +Subject: soc: qcom: gsbi: fix double disable caused by devm + +From: Haotian Zhang + +[ Upstream commit 2286e18e3937c69cc103308a8c1d4898d8a7b04f ] + +In the commit referenced by the Fixes tag, devm_clk_get_enabled() was +introduced to replace devm_clk_get() and clk_prepare_enable(). While +the clk_disable_unprepare() call in the error path was correctly +removed, the one in the remove function was overlooked, leading to a +double disable issue. + +Remove the redundant clk_disable_unprepare() call from gsbi_remove() +to fix this issue. Since all resources are now managed by devres +and will be automatically released, the remove function serves no purpose +and can be deleted entirely. + +Fixes: 489d7a8cc286 ("soc: qcom: use devm_clk_get_enabled() in gsbi_probe()") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/stable/20251020160215.523-1-vulab%40iscas.ac.cn +Link: https://lore.kernel.org/r/20251020160215.523-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/qcom_gsbi.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c +index 8f1158e0c6313..a25d1de592f06 100644 +--- a/drivers/soc/qcom/qcom_gsbi.c ++++ b/drivers/soc/qcom/qcom_gsbi.c +@@ -212,13 +212,6 @@ static int gsbi_probe(struct platform_device *pdev) + return of_platform_populate(node, NULL, NULL, &pdev->dev); + } + +-static void gsbi_remove(struct platform_device *pdev) +-{ +- struct gsbi_info *gsbi = platform_get_drvdata(pdev); +- +- clk_disable_unprepare(gsbi->hclk); +-} +- + static const struct of_device_id gsbi_dt_match[] = { + { .compatible = "qcom,gsbi-v1.0.0", }, + { }, +@@ -232,7 +225,6 @@ static struct platform_driver gsbi_driver = { + .of_match_table = gsbi_dt_match, + }, + .probe = gsbi_probe, +- .remove = gsbi_remove, + }; + + module_platform_driver(gsbi_driver); +-- +2.51.0 + diff --git a/queue-6.17/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.17/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..1f50c1be06 --- /dev/null +++ b/queue-6.17/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,51 @@ +From a7254c41b9639be407d0729bc9b3cd9731efcff7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:27:33 +0800 +Subject: soc: qcom: smem: fix hwspinlock resource leak in probe error paths + +From: Haotian Zhang + +[ Upstream commit dc5db35073a19f6d3c30bea367b551c1a784ef8f ] + +The hwspinlock acquired via hwspin_lock_request_specific() is not +released on several error paths. This results in resource leakage +when probe fails. + +Switch to devm_hwspin_lock_request_specific() to automatically +handle cleanup on probe failure. Remove the manual hwspin_lock_free() +in qcom_smem_remove() as devm handles it automatically. + +Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/smem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index c4c45f15dca4f..f1d1b5aa5e4db 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1190,7 +1190,7 @@ static int qcom_smem_probe(struct platform_device *pdev) + return dev_err_probe(&pdev->dev, hwlock_id, + "failed to retrieve hwlock\n"); + +- smem->hwlock = hwspin_lock_request_specific(hwlock_id); ++ smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); + if (!smem->hwlock) + return -ENXIO; + +@@ -1243,7 +1243,6 @@ static void qcom_smem_remove(struct platform_device *pdev) + { + platform_device_unregister(__smem->socinfo); + +- hwspin_lock_free(__smem->hwlock); + __smem = NULL; + } + +-- +2.51.0 + diff --git a/queue-6.17/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch b/queue-6.17/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch new file mode 100644 index 0000000000..523bd1c1da --- /dev/null +++ b/queue-6.17/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch @@ -0,0 +1,112 @@ +From b6ab20e9c4c0ad696e1b247ea44555a24180e75d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 02:40:45 +0300 +Subject: spi: airoha-snfi: en7523: workaround flash damaging if UART_TXD was + short to GND + +From: Mikhail Kshevetskiy + +[ Upstream commit 061795b345aff371df8f71d54ae7c7dc8ae630d0 ] + +Airoha EN7523 specific bug +-------------------------- +We found that some serial console may pull TX line to GROUND during board +boot time. Airoha uses TX line as one of its bootstrap pins. On the EN7523 +SoC this may lead to booting in RESERVED boot mode. + +It was found that some flashes operates incorrectly in RESERVED mode. +Micron and Skyhigh flashes are definitely affected by the issue, +Winbond flashes are not affected. + +Details: +-------- +DMA reading of odd pages on affected flashes operates incorrectly. Page +reading offset (start of the page) on hardware level is replaced by 0x10. +Thus results in incorrect data reading. As result OS loading becomes +impossible. + +Usage of UBI make things even worse. On attaching, UBI will detects +corruptions (because of wrong reading of odd pages) and will try to +recover. For recovering UBI will erase and write 'damaged' blocks with +a valid information. This will destroy all UBI data. + +Non-DMA reading is OK. + +This patch detects booting in reserved mode, turn off DMA and print big +fat warning. + +It's worth noting that the boot configuration is preserved across reboots. +Therefore, to boot normally, you should do the following: +- disconnect the serial console from the board, +- power cycle the board. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251125234047.1101985-2-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index b78163eaed61d..20b5d469d519a 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -1030,6 +1030,11 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = { + .dirmap_write = airoha_snand_dirmap_write, + }; + ++static const struct spi_controller_mem_ops airoha_snand_nodma_mem_ops = { ++ .supports_op = airoha_snand_supports_op, ++ .exec_op = airoha_snand_exec_op, ++}; ++ + static int airoha_snand_setup(struct spi_device *spi) + { + struct airoha_snand_ctrl *as_ctrl; +@@ -1104,7 +1109,9 @@ static int airoha_snand_probe(struct platform_device *pdev) + struct airoha_snand_ctrl *as_ctrl; + struct device *dev = &pdev->dev; + struct spi_controller *ctrl; ++ bool dma_enable = true; + void __iomem *base; ++ u32 sfc_strap; + int err; + + ctrl = devm_spi_alloc_host(dev, sizeof(*as_ctrl)); +@@ -1139,12 +1146,28 @@ static int airoha_snand_probe(struct platform_device *pdev) + return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk), + "unable to get spi clk\n"); + ++ if (device_is_compatible(dev, "airoha,en7523-snand")) { ++ err = regmap_read(as_ctrl->regmap_ctrl, ++ REG_SPI_CTRL_SFC_STRAP, &sfc_strap); ++ if (err) ++ return err; ++ ++ if (!(sfc_strap & 0x04)) { ++ dma_enable = false; ++ dev_warn(dev, "Detected booting in RESERVED mode (UART_TXD was short to GND).\n"); ++ dev_warn(dev, "This mode is known for incorrect DMA reading of some flashes.\n"); ++ dev_warn(dev, "Much slower PIO mode will be used to prevent flash data damage.\n"); ++ dev_warn(dev, "Unplug UART cable and power cycle board to get full performance.\n"); ++ } ++ } ++ + err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32)); + if (err) + return err; + + ctrl->num_chipselect = 2; +- ctrl->mem_ops = &airoha_snand_mem_ops; ++ ctrl->mem_ops = dma_enable ? &airoha_snand_mem_ops ++ : &airoha_snand_nodma_mem_ops; + ctrl->bits_per_word_mask = SPI_BPW_MASK(8); + ctrl->mode_bits = SPI_RX_DUAL; + ctrl->setup = airoha_snand_setup; +-- +2.51.0 + diff --git a/queue-6.17/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch b/queue-6.17/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch new file mode 100644 index 0000000000..23cab54142 --- /dev/null +++ b/queue-6.17/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch @@ -0,0 +1,50 @@ +From cfde1e35cd0cc812940b213003215ca934931f1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 16:06:30 +0800 +Subject: spi: ch341: fix out-of-bounds memory access in ch341_transfer_one + +From: Tianchu Chen + +[ Upstream commit 545d1287e40a55242f6ab68bcc1ba3b74088b1bc ] + +Discovered by Atuin - Automated Vulnerability Discovery Engine. + +The 'len' variable is calculated as 'min(32, trans->len + 1)', +which includes the 1-byte command header. + +When copying data from 'trans->tx_buf' to 'ch341->tx_buf + 1', using 'len' +as the length is incorrect because: + +1. It causes an out-of-bounds read from 'trans->tx_buf' (which has size + 'trans->len', i.e., 'len - 1' in this context). +2. It can cause an out-of-bounds write to 'ch341->tx_buf' if 'len' is + CH341_PACKET_LENGTH (32). Writing 32 bytes to ch341->tx_buf + 1 + overflows the buffer. + +Fix this by copying 'len - 1' bytes. + +Fixes: 8846739f52af ("spi: add ch341a usb2spi driver") +Signed-off-by: Tianchu Chen +Link: https://patch.msgid.link/20251128160630.0f922c45ec6084a46fb57099@linux.dev +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-ch341.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c +index 46bc208f2d050..79d2f9ab4ef03 100644 +--- a/drivers/spi/spi-ch341.c ++++ b/drivers/spi/spi-ch341.c +@@ -78,7 +78,7 @@ static int ch341_transfer_one(struct spi_controller *host, + + ch341->tx_buf[0] = CH341A_CMD_SPI_STREAM; + +- memcpy(ch341->tx_buf + 1, trans->tx_buf, len); ++ memcpy(ch341->tx_buf + 1, trans->tx_buf, len - 1); + + ret = usb_bulk_msg(ch341->udev, ch341->write_pipe, ch341->tx_buf, len, + NULL, CH341_DEFAULT_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.17/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch b/queue-6.17/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch new file mode 100644 index 0000000000..990a301389 --- /dev/null +++ b/queue-6.17/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch @@ -0,0 +1,47 @@ +From a5c1d5a9af6d30e74d9038457319b82c404984ae Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 17:05:39 +0800 +Subject: spi: sophgo: Fix incorrect use of bus width value macros + +From: Longbin Li + +[ Upstream commit d9813cd23d5a7b254cc1b1c1ea042634d8da62e6 ] + +The previous code initialized the 'reg' value with specific bus-width +values (BUS_WIDTH_2_BIT and BUS_WIDTH_4_BIT), which introduces ambiguity. +Replace them with BUS_WIDTH_MASK to express the intention clearly. + +Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver") +Signed-off-by: Longbin Li +Link: https://patch.msgid.link/20251117090559.78288-1-looong.bin@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-sg2044-nor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c +index af48b1fcda930..37f1cfe10be46 100644 +--- a/drivers/spi/spi-sg2044-nor.c ++++ b/drivers/spi/spi-sg2044-nor.c +@@ -42,6 +42,7 @@ + #define SPIFMC_TRAN_CSR_TRAN_MODE_RX BIT(0) + #define SPIFMC_TRAN_CSR_TRAN_MODE_TX BIT(1) + #define SPIFMC_TRAN_CSR_FAST_MODE BIT(3) ++#define SPIFMC_TRAN_CSR_BUS_WIDTH_MASK GENMASK(5, 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_1_BIT (0x00 << 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT (0x01 << 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT (0x02 << 4) +@@ -122,8 +123,7 @@ static u32 sg2044_spifmc_init_reg(struct sg2044_spifmc *spifmc) + reg = readl(spifmc->io_base + SPIFMC_TRAN_CSR); + reg &= ~(SPIFMC_TRAN_CSR_TRAN_MODE_MASK | + SPIFMC_TRAN_CSR_FAST_MODE | +- SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT | +- SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT | ++ SPIFMC_TRAN_CSR_BUS_WIDTH_MASK | + SPIFMC_TRAN_CSR_DMA_EN | + SPIFMC_TRAN_CSR_ADDR_BYTES_MASK | + SPIFMC_TRAN_CSR_WITH_CMD | +-- +2.51.0 + diff --git a/queue-6.17/spi-tegra210-quad-fix-timeout-handling.patch b/queue-6.17/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..208b043032 --- /dev/null +++ b/queue-6.17/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,117 @@ +From 0e86fe6b3eff672c948f88d96287666906c196bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 3be7499db21ec..d9ca3d7b082f2 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -1024,8 +1024,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1176,9 +1178,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1200,11 +1204,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + ret = 0; + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1290,6 +1296,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1395,6 +1403,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1480,6 +1489,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-6.17/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-6.17/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..1560afbd74 --- /dev/null +++ b/queue-6.17/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From d14380c073f069da9312de8029eff25cb10584d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 9e7b84071174c..8a5ccc8ae0a18 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1171,8 +1171,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-6.17/staging-most-remove-broken-i2c-driver.patch b/queue-6.17/staging-most-remove-broken-i2c-driver.patch new file mode 100644 index 0000000000..042ab48c99 --- /dev/null +++ b/queue-6.17/staging-most-remove-broken-i2c-driver.patch @@ -0,0 +1,467 @@ +From e73ba727189aadcd9c2979bef1ea3e6c08e77b52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:34:42 +0100 +Subject: staging: most: remove broken i2c driver + +From: Johan Hovold + +[ Upstream commit 495df2da6944477d282d5cc0c13174d06e25b310 ] + +The MOST I2C driver has been completely broken for five years without +anyone noticing so remove the driver from staging. + +Specifically, commit 723de0f9171e ("staging: most: remove device from +interface structure") started requiring drivers to set the interface +device pointer before registration, but the I2C driver was never updated +which results in a NULL pointer dereference if anyone ever tries to +probe it. + +Fixes: 723de0f9171e ("staging: most: remove device from interface structure") +Cc: Christian Gromm +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20251029093442.29256-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/most/Kconfig | 2 - + drivers/staging/most/Makefile | 1 - + drivers/staging/most/i2c/Kconfig | 13 -- + drivers/staging/most/i2c/Makefile | 4 - + drivers/staging/most/i2c/i2c.c | 374 ------------------------------ + 5 files changed, 394 deletions(-) + delete mode 100644 drivers/staging/most/i2c/Kconfig + delete mode 100644 drivers/staging/most/i2c/Makefile + delete mode 100644 drivers/staging/most/i2c/i2c.c + +diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig +index 6f420cbcdcfff..e89658df6f124 100644 +--- a/drivers/staging/most/Kconfig ++++ b/drivers/staging/most/Kconfig +@@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig" + + source "drivers/staging/most/dim2/Kconfig" + +-source "drivers/staging/most/i2c/Kconfig" +- + endif +diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile +index 8b3fc5a7af514..e45084df7803a 100644 +--- a/drivers/staging/most/Makefile ++++ b/drivers/staging/most/Makefile +@@ -3,4 +3,3 @@ + obj-$(CONFIG_MOST_NET) += net/ + obj-$(CONFIG_MOST_VIDEO) += video/ + obj-$(CONFIG_MOST_DIM2) += dim2/ +-obj-$(CONFIG_MOST_I2C) += i2c/ +diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig +deleted file mode 100644 +index ff64283cbad18..0000000000000 +--- a/drivers/staging/most/i2c/Kconfig ++++ /dev/null +@@ -1,13 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-# +-# MOST I2C configuration +-# +- +-config MOST_I2C +- tristate "I2C" +- depends on I2C +- help +- Say Y here if you want to connect via I2C to network transceiver. +- +- To compile this driver as a module, choose M here: the +- module will be called most_i2c. +diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile +deleted file mode 100644 +index 71099dd0f85b9..0000000000000 +--- a/drivers/staging/most/i2c/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_MOST_I2C) += most_i2c.o +- +-most_i2c-objs := i2c.o +diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c +deleted file mode 100644 +index 184b2dd11fc34..0000000000000 +--- a/drivers/staging/most/i2c/i2c.c ++++ /dev/null +@@ -1,374 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * i2c.c - Hardware Dependent Module for I2C Interface +- * +- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-enum { CH_RX, CH_TX, NUM_CHANNELS }; +- +-#define MAX_BUFFERS_CONTROL 32 +-#define MAX_BUF_SIZE_CONTROL 256 +- +-/** +- * list_first_mbo - get the first mbo from a list +- * @ptr: the list head to take the mbo from. +- */ +-#define list_first_mbo(ptr) \ +- list_first_entry(ptr, struct mbo, list) +- +-static unsigned int polling_rate; +-module_param(polling_rate, uint, 0644); +-MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)"); +- +-struct hdm_i2c { +- struct most_interface most_iface; +- struct most_channel_capability capabilities[NUM_CHANNELS]; +- struct i2c_client *client; +- struct rx { +- struct delayed_work dwork; +- struct list_head list; +- bool int_disabled; +- unsigned int delay; +- } rx; +- char name[64]; +-}; +- +-static inline struct hdm_i2c *to_hdm(struct most_interface *iface) +-{ +- return container_of(iface, struct hdm_i2c, most_iface); +-} +- +-static irqreturn_t most_irq_handler(int, void *); +-static void pending_rx_work(struct work_struct *); +- +-/** +- * configure_channel - called from MOST core to configure a channel +- * @most_iface: interface the channel belongs to +- * @ch_idx: channel to be configured +- * @channel_config: structure that holds the configuration information +- * +- * Return 0 on success, negative on failure. +- * +- * Receives configuration information from MOST core and initialize the +- * corresponding channel. +- */ +-static int configure_channel(struct most_interface *most_iface, +- int ch_idx, +- struct most_channel_config *channel_config) +-{ +- int ret; +- struct hdm_i2c *dev = to_hdm(most_iface); +- unsigned int delay, pr; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (channel_config->data_type != MOST_CH_CONTROL) { +- pr_err("bad data type for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction != dev->capabilities[ch_idx].direction) { +- pr_err("bad direction for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction == MOST_CH_RX) { +- if (!polling_rate) { +- if (dev->client->irq <= 0) { +- pr_err("bad irq: %d\n", dev->client->irq); +- return -ENOENT; +- } +- dev->rx.int_disabled = false; +- ret = request_irq(dev->client->irq, most_irq_handler, 0, +- dev->client->name, dev); +- if (ret) { +- pr_err("request_irq(%d) failed: %d\n", +- dev->client->irq, ret); +- return ret; +- } +- } else { +- delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate); +- dev->rx.delay = delay ? delay : 1; +- pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay); +- pr_info("polling rate is %u Hz\n", pr); +- } +- } +- +- return 0; +-} +- +-/** +- * enqueue - called from MOST core to enqueue a buffer for data transfer +- * @most_iface: intended interface +- * @ch_idx: ID of the channel the buffer is intended for +- * @mbo: pointer to the buffer object +- * +- * Return 0 on success, negative on failure. +- * +- * Transmit the data over I2C if it is a "write" request or push the buffer into +- * list if it is an "read" request +- */ +-static int enqueue(struct most_interface *most_iface, +- int ch_idx, struct mbo *mbo) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- int ret; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- /* RX */ +- if (!polling_rate) +- disable_irq(dev->client->irq); +- cancel_delayed_work_sync(&dev->rx.dwork); +- list_add_tail(&mbo->list, &dev->rx.list); +- if (dev->rx.int_disabled || polling_rate) +- pending_rx_work(&dev->rx.dwork.work); +- if (!polling_rate) +- enable_irq(dev->client->irq); +- } else { +- /* TX */ +- ret = i2c_master_send(dev->client, mbo->virt_address, +- mbo->buffer_length); +- if (ret <= 0) { +- mbo->processed_length = 0; +- mbo->status = MBO_E_INVAL; +- } else { +- mbo->processed_length = mbo->buffer_length; +- mbo->status = MBO_SUCCESS; +- } +- mbo->complete(mbo); +- } +- +- return 0; +-} +- +-/** +- * poison_channel - called from MOST core to poison buffers of a channel +- * @most_iface: pointer to the interface the channel to be poisoned belongs to +- * @ch_idx: corresponding channel ID +- * +- * Return 0 on success, negative on failure. +- * +- * If channel direction is RX, complete the buffers in list with +- * status MBO_E_CLOSE +- */ +-static int poison_channel(struct most_interface *most_iface, +- int ch_idx) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- struct mbo *mbo; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- if (!polling_rate) +- free_irq(dev->client->irq, dev); +- cancel_delayed_work_sync(&dev->rx.dwork); +- +- while (!list_empty(&dev->rx.list)) { +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = 0; +- mbo->status = MBO_E_CLOSE; +- mbo->complete(mbo); +- } +- } +- +- return 0; +-} +- +-static void do_rx_work(struct hdm_i2c *dev) +-{ +- struct mbo *mbo; +- unsigned char msg[MAX_BUF_SIZE_CONTROL]; +- int ret; +- u16 pml, data_size; +- +- /* Read PML (2 bytes) */ +- ret = i2c_master_recv(dev->client, msg, 2); +- if (ret <= 0) { +- pr_err("Failed to receive PML\n"); +- return; +- } +- +- pml = (msg[0] << 8) | msg[1]; +- if (!pml) +- return; +- +- data_size = pml + 2; +- +- /* Read the whole message, including PML */ +- ret = i2c_master_recv(dev->client, msg, data_size); +- if (ret <= 0) { +- pr_err("Failed to receive a Port Message\n"); +- return; +- } +- +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = min(data_size, mbo->buffer_length); +- memcpy(mbo->virt_address, msg, mbo->processed_length); +- mbo->status = MBO_SUCCESS; +- mbo->complete(mbo); +-} +- +-/** +- * pending_rx_work - Read pending messages through I2C +- * @work: definition of this work item +- * +- * Invoked by the Interrupt Service Routine, most_irq_handler() +- */ +-static void pending_rx_work(struct work_struct *work) +-{ +- struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work); +- +- if (list_empty(&dev->rx.list)) +- return; +- +- do_rx_work(dev); +- +- if (polling_rate) { +- schedule_delayed_work(&dev->rx.dwork, dev->rx.delay); +- } else { +- dev->rx.int_disabled = false; +- enable_irq(dev->client->irq); +- } +-} +- +-/* +- * most_irq_handler - Interrupt Service Routine +- * @irq: irq number +- * @_dev: private data +- * +- * Schedules a delayed work +- * +- * By default the interrupt line behavior is Active Low. Once an interrupt is +- * generated by the device, until driver clears the interrupt (by reading +- * the PMP message), device keeps the interrupt line in low state. Since i2c +- * read is done in work queue, the interrupt line must be disabled temporarily +- * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue, +- * after reading the message. +- * +- * Note: If we use the interrupt line in Falling edge mode, there is a +- * possibility to miss interrupts when ISR is getting executed. +- * +- */ +-static irqreturn_t most_irq_handler(int irq, void *_dev) +-{ +- struct hdm_i2c *dev = _dev; +- +- disable_irq_nosync(irq); +- dev->rx.int_disabled = true; +- schedule_delayed_work(&dev->rx.dwork, 0); +- +- return IRQ_HANDLED; +-} +- +-/* +- * i2c_probe - i2c probe handler +- * @client: i2c client device structure +- * @id: i2c client device id +- * +- * Return 0 on success, negative on failure. +- * +- * Register the i2c client device as a MOST interface +- */ +-static int i2c_probe(struct i2c_client *client) +-{ +- struct hdm_i2c *dev; +- int ret, i; +- +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); +- if (!dev) +- return -ENOMEM; +- +- /* ID format: i2c--
*/ +- snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x", +- client->adapter->nr, client->addr); +- +- for (i = 0; i < NUM_CHANNELS; i++) { +- dev->capabilities[i].data_type = MOST_CH_CONTROL; +- dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL; +- dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL; +- } +- dev->capabilities[CH_RX].direction = MOST_CH_RX; +- dev->capabilities[CH_RX].name_suffix = "rx"; +- dev->capabilities[CH_TX].direction = MOST_CH_TX; +- dev->capabilities[CH_TX].name_suffix = "tx"; +- +- dev->most_iface.interface = ITYPE_I2C; +- dev->most_iface.description = dev->name; +- dev->most_iface.num_channels = NUM_CHANNELS; +- dev->most_iface.channel_vector = dev->capabilities; +- dev->most_iface.configure = configure_channel; +- dev->most_iface.enqueue = enqueue; +- dev->most_iface.poison_channel = poison_channel; +- +- INIT_LIST_HEAD(&dev->rx.list); +- +- INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work); +- +- dev->client = client; +- i2c_set_clientdata(client, dev); +- +- ret = most_register_interface(&dev->most_iface); +- if (ret) { +- pr_err("Failed to register i2c as a MOST interface\n"); +- kfree(dev); +- return ret; +- } +- +- return 0; +-} +- +-/* +- * i2c_remove - i2c remove handler +- * @client: i2c client device structure +- * +- * Return 0 on success. +- * +- * Unregister the i2c client device as a MOST interface +- */ +-static void i2c_remove(struct i2c_client *client) +-{ +- struct hdm_i2c *dev = i2c_get_clientdata(client); +- +- most_deregister_interface(&dev->most_iface); +- kfree(dev); +-} +- +-static const struct i2c_device_id i2c_id[] = { +- { "most_i2c" }, +- { } /* Terminating entry */ +-}; +- +-MODULE_DEVICE_TABLE(i2c, i2c_id); +- +-static struct i2c_driver i2c_driver = { +- .driver = { +- .name = "hdm_i2c", +- }, +- .probe = i2c_probe, +- .remove = i2c_remove, +- .id_table = i2c_id, +-}; +- +-module_i2c_driver(i2c_driver); +- +-MODULE_AUTHOR("Andrey Shvetsov "); +-MODULE_DESCRIPTION("I2C Hardware Dependent Module"); +-MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.17/task_work-fix-nmi-race-condition.patch b/queue-6.17/task_work-fix-nmi-race-condition.patch new file mode 100644 index 0000000000..10655283c5 --- /dev/null +++ b/queue-6.17/task_work-fix-nmi-race-condition.patch @@ -0,0 +1,62 @@ +From d7c6a6873d7a5201be0e78ea2f7a0d1be5d1288d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 15:47:00 +0200 +Subject: task_work: Fix NMI race condition + +From: Peter Zijlstra + +[ Upstream commit ef1ea98c8fffe227e5319215d84a53fa2a4bcebc ] + + __schedule() + // disable irqs + + task_work_add(current, work, TWA_NMI_CURRENT); + + // current = next; + // enable irqs + + task_work_set_notify_irq() + test_and_set_tsk_thread_flag(current, + TIF_NOTIFY_RESUME); // wrong task! + + // original task skips task work on its next return to user (or exit!) + +Fixes: 466e4d801cd4 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode.") +Reported-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Steven Rostedt (Google) +Link: https://patch.msgid.link/20250924080118.425949403@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/task_work.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/task_work.c b/kernel/task_work.c +index d1efec571a4a4..0f7519f8e7c93 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -9,7 +9,12 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ + #ifdef CONFIG_IRQ_WORK + static void task_work_set_notify_irq(struct irq_work *entry) + { +- test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); ++ /* ++ * no-op IPI ++ * ++ * TWA_NMI_CURRENT will already have set the TIF flag, all ++ * this interrupt does it tickle the return-to-user path. ++ */ + } + static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = + IRQ_WORK_INIT_HARD(task_work_set_notify_irq); +@@ -86,6 +91,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, + break; + #ifdef CONFIG_IRQ_WORK + case TWA_NMI_CURRENT: ++ set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); + irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); + break; + #endif +-- +2.51.0 + diff --git a/queue-6.17/timers-migration-convert-while-loops-to-use-for.patch b/queue-6.17/timers-migration-convert-while-loops-to-use-for.patch new file mode 100644 index 0000000000..8bf3c1ccf2 --- /dev/null +++ b/queue-6.17/timers-migration-convert-while-loops-to-use-for.patch @@ -0,0 +1,83 @@ +From 4c9e2b29eb1bd43c9a3e1b6c6356f70f2dada957 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:31 +0200 +Subject: timers/migration: Convert "while" loops to use "for" + +From: Frederic Weisbecker + +[ Upstream commit 6c181b5667eea3e6564d334443536a5974190e15 ] + +Both the "do while" and "while" loops in tmigr_setup_groups() eventually +mimic the behaviour of "for" loops. + +Simplify accordingly. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-2-frederic@kernel.org +Stable-dep-of: 5eb579dfd46b ("timers/migration: Fix imbalanced NUMA trees") +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index c0c54dc5314c3..1e371f1fdc86c 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -1642,22 +1642,23 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + { + struct tmigr_group *group, *child, **stack; +- int top = 0, err = 0, i = 0; ++ int i, top = 0, err = 0; + struct list_head *lvllist; + + stack = kcalloc(tmigr_hierarchy_levels, sizeof(*stack), GFP_KERNEL); + if (!stack) + return -ENOMEM; + +- do { ++ for (i = 0; i < tmigr_hierarchy_levels; i++) { + group = tmigr_get_group(cpu, node, i); + if (IS_ERR(group)) { + err = PTR_ERR(group); ++ i--; + break; + } + + top = i; +- stack[i++] = group; ++ stack[i] = group; + + /* + * When booting only less CPUs of a system than CPUs are +@@ -1667,16 +1668,18 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + * be different from tmigr_hierarchy_levels, contains only a + * single group. + */ +- if (group->parent || list_is_singular(&tmigr_level_list[i - 1])) ++ if (group->parent || list_is_singular(&tmigr_level_list[i])) + break; ++ } + +- } while (i < tmigr_hierarchy_levels); +- +- /* Assert single root */ +- WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top])); ++ /* Assert single root without parent */ ++ if (WARN_ON_ONCE(i >= tmigr_hierarchy_levels)) ++ return -EINVAL; ++ if (WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top]))) ++ return -EINVAL; + +- while (i > 0) { +- group = stack[--i]; ++ for (; i >= 0; i--) { ++ group = stack[i]; + + if (err < 0) { + list_del(&group->list); +-- +2.51.0 + diff --git a/queue-6.17/timers-migration-fix-imbalanced-numa-trees.patch b/queue-6.17/timers-migration-fix-imbalanced-numa-trees.patch new file mode 100644 index 0000000000..7f9336386a --- /dev/null +++ b/queue-6.17/timers-migration-fix-imbalanced-numa-trees.patch @@ -0,0 +1,441 @@ +From 65ef70f0969b3fdd2c6f068d795e5f92ea1a61af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:33 +0200 +Subject: timers/migration: Fix imbalanced NUMA trees + +From: Frederic Weisbecker + +[ Upstream commit 5eb579dfd46b4949117ecb0f1ba2f12d3dc9a6f2 ] + +When a CPU from a new node boots, the old root may happen to be +connected to the new root even if their node mismatch, as depicted in +the following scenario: + +1) CPU 0 boots and creates the first group for node 0. + + [GRP0:0] + node 0 + | + CPU 0 + +2) CPU 1 from node 1 boots and creates a new top that corresponds to + node 1, but it also connects the old root from node 0 to the new root + from node 1 by mistake. + + [GRP1:0] + node 1 + / \ + / \ + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0 CPU 1 + +3) This eventually leads to an imbalanced tree where some node 0 CPUs + migrate node 1 timers (and vice versa) way before reaching the + crossnode groups, resulting in more frequent remote memory accesses + than expected. + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:1] + node 1 node 0 + / \ | + / \ [...] + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0... CPU 1... + +A balanced tree should only contain groups having children that belong +to the same node: + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:0] + node 0 node 1 + / \ / \ + / \ / \ + [GRP0:0] [...] [...] [GRP0:1] + node 0 node 1 + | | + CPU 0... CPU 1... + +In order to fix this, the hierarchy must be unfolded up to the crossnode +level as soon as a node mismatch is detected. For example the stage 2 +above should lead to this layout: + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:1] + node 0 node 1 + / \ + / \ + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0 CPU 1 + +This means that not only GRP1:0 must be created but also GRP1:1 and +GRP2:0 in order to prepare a balanced tree for next CPUs to boot. + +Fixes: 7ee988770326 ("timers: Implement the hierarchical pull model") +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-4-frederic@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 231 +++++++++++++++++++--------------- + 1 file changed, 127 insertions(+), 104 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index 5f8aef94ca0f7..49635a2b7ee28 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -420,6 +420,8 @@ static struct list_head *tmigr_level_list __read_mostly; + static unsigned int tmigr_hierarchy_levels __read_mostly; + static unsigned int tmigr_crossnode_level __read_mostly; + ++static struct tmigr_group *tmigr_root; ++ + static DEFINE_PER_CPU(struct tmigr_cpu, tmigr_cpu); + + #define TMIGR_NONE 0xFF +@@ -522,11 +524,9 @@ struct tmigr_walk { + + typedef bool (*up_f)(struct tmigr_group *, struct tmigr_group *, struct tmigr_walk *); + +-static void __walk_groups(up_f up, struct tmigr_walk *data, +- struct tmigr_cpu *tmc) ++static void __walk_groups_from(up_f up, struct tmigr_walk *data, ++ struct tmigr_group *child, struct tmigr_group *group) + { +- struct tmigr_group *child = NULL, *group = tmc->tmgroup; +- + do { + WARN_ON_ONCE(group->level >= tmigr_hierarchy_levels); + +@@ -544,6 +544,12 @@ static void __walk_groups(up_f up, struct tmigr_walk *data, + } while (group); + } + ++static void __walk_groups(up_f up, struct tmigr_walk *data, ++ struct tmigr_cpu *tmc) ++{ ++ __walk_groups_from(up, data, NULL, tmc->tmgroup); ++} ++ + static void walk_groups(up_f up, struct tmigr_walk *data, struct tmigr_cpu *tmc) + { + lockdep_assert_held(&tmc->lock); +@@ -1498,21 +1504,6 @@ static void tmigr_init_group(struct tmigr_group *group, unsigned int lvl, + s.seq = 0; + atomic_set(&group->migr_state, s.state); + +- /* +- * If this is a new top-level, prepare its groupmask in advance. +- * This avoids accidents where yet another new top-level is +- * created in the future and made visible before the current groupmask. +- */ +- if (list_empty(&tmigr_level_list[lvl])) { +- group->groupmask = BIT(0); +- /* +- * The previous top level has prepared its groupmask already, +- * simply account it as the first child. +- */ +- if (lvl > 0) +- group->num_children = 1; +- } +- + timerqueue_init_head(&group->events); + timerqueue_init(&group->groupevt.nextevt); + group->groupevt.nextevt.expires = KTIME_MAX; +@@ -1567,22 +1558,51 @@ static struct tmigr_group *tmigr_get_group(unsigned int cpu, int node, + return group; + } + ++static bool tmigr_init_root(struct tmigr_group *group, bool activate) ++{ ++ if (!group->parent && group != tmigr_root) { ++ /* ++ * This is the new top-level, prepare its groupmask in advance ++ * to avoid accidents where yet another new top-level is ++ * created in the future and made visible before this groupmask. ++ */ ++ group->groupmask = BIT(0); ++ WARN_ON_ONCE(activate); ++ ++ return true; ++ } ++ ++ return false; ++ ++} ++ + static void tmigr_connect_child_parent(struct tmigr_group *child, + struct tmigr_group *parent, + bool activate) + { +- struct tmigr_walk data; ++ if (tmigr_init_root(parent, activate)) { ++ /* ++ * The previous top level had prepared its groupmask already, ++ * simply account it in advance as the first child. If some groups ++ * have been created between the old and new root due to node ++ * mismatch, the new root's child will be intialized accordingly. ++ */ ++ parent->num_children = 1; ++ } + +- if (activate) { ++ /* Connecting old root to new root ? */ ++ if (!parent->parent && activate) { + /* +- * @child is the old top and @parent the new one. In this +- * case groupmask is pre-initialized and @child already +- * accounted, along with its new sibling corresponding to the +- * CPU going up. ++ * @child is the old top, or in case of node mismatch, some ++ * intermediate group between the old top and the new one in ++ * @parent. In this case the @child must be pre-accounted above ++ * as the first child. Its new inactive sibling corresponding ++ * to the CPU going up has been accounted as the second child. + */ +- WARN_ON_ONCE(child->groupmask != BIT(0) || parent->num_children != 2); ++ WARN_ON_ONCE(parent->num_children != 2); ++ child->groupmask = BIT(0); + } else { +- /* Adding @child for the CPU going up to @parent. */ ++ /* Common case adding @child for the CPU going up to @parent. */ + child->groupmask = BIT(parent->num_children++); + } + +@@ -1594,56 +1614,28 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + smp_store_release(&child->parent, parent); + + trace_tmigr_connect_child_parent(child); +- +- if (!activate) +- return; +- +- /* +- * To prevent inconsistent states, active children need to be active in +- * the new parent as well. Inactive children are already marked inactive +- * in the parent group: +- * +- * * When new groups were created by tmigr_setup_groups() starting from +- * the lowest level (and not higher then one level below the current +- * top level), then they are not active. They will be set active when +- * the new online CPU comes active. +- * +- * * But if a new group above the current top level is required, it is +- * mandatory to propagate the active state of the already existing +- * child to the new parent. So tmigr_connect_child_parent() is +- * executed with the formerly top level group (child) and the newly +- * created group (parent). +- * +- * * It is ensured that the child is active, as this setup path is +- * executed in hotplug prepare callback. This is exectued by an +- * already connected and !idle CPU. Even if all other CPUs go idle, +- * the CPU executing the setup will be responsible up to current top +- * level group. And the next time it goes inactive, it will release +- * the new childmask and parent to subsequent walkers through this +- * @child. Therefore propagate active state unconditionally. +- */ +- data.childmask = child->groupmask; +- +- /* +- * There is only one new level per time (which is protected by +- * tmigr_mutex). When connecting the child and the parent and set the +- * child active when the parent is inactive, the parent needs to be the +- * uppermost level. Otherwise there went something wrong! +- */ +- WARN_ON(!tmigr_active_up(parent, child, &data) && parent->parent); + } + +-static int tmigr_setup_groups(unsigned int cpu, unsigned int node) ++static int tmigr_setup_groups(unsigned int cpu, unsigned int node, ++ struct tmigr_group *start, bool activate) + { + struct tmigr_group *group, *child, **stack; +- int i, top = 0, err = 0; +- struct list_head *lvllist; ++ int i, top = 0, err = 0, start_lvl = 0; ++ bool root_mismatch = false; + + stack = kcalloc(tmigr_hierarchy_levels, sizeof(*stack), GFP_KERNEL); + if (!stack) + return -ENOMEM; + +- for (i = 0; i < tmigr_hierarchy_levels; i++) { ++ if (start) { ++ stack[start->level] = start; ++ start_lvl = start->level + 1; ++ } ++ ++ if (tmigr_root) ++ root_mismatch = tmigr_root->numa_node != node; ++ ++ for (i = start_lvl; i < tmigr_hierarchy_levels; i++) { + group = tmigr_get_group(cpu, node, i); + if (IS_ERR(group)) { + err = PTR_ERR(group); +@@ -1656,23 +1648,25 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + + /* + * When booting only less CPUs of a system than CPUs are +- * available, not all calculated hierarchy levels are required. ++ * available, not all calculated hierarchy levels are required, ++ * unless a node mismatch is detected. + * + * The loop is aborted as soon as the highest level, which might + * be different from tmigr_hierarchy_levels, contains only a +- * single group. ++ * single group, unless the nodes mismatch below tmigr_crossnode_level + */ +- if (group->parent || list_is_singular(&tmigr_level_list[i])) ++ if (group->parent) ++ break; ++ if ((!root_mismatch || i >= tmigr_crossnode_level) && ++ list_is_singular(&tmigr_level_list[i])) + break; + } + + /* Assert single root without parent */ + if (WARN_ON_ONCE(i >= tmigr_hierarchy_levels)) + return -EINVAL; +- if (WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top]))) +- return -EINVAL; + +- for (; i >= 0; i--) { ++ for (; i >= start_lvl; i--) { + group = stack[i]; + + if (err < 0) { +@@ -1692,48 +1686,63 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + tmc->tmgroup = group; + tmc->groupmask = BIT(group->num_children++); + ++ tmigr_init_root(group, activate); ++ + trace_tmigr_connect_cpu_parent(tmc); + + /* There are no children that need to be connected */ + continue; + } else { + child = stack[i - 1]; +- /* Will be activated at online time */ +- tmigr_connect_child_parent(child, group, false); ++ tmigr_connect_child_parent(child, group, activate); + } ++ } + +- /* check if uppermost level was newly created */ +- if (top != i) +- continue; +- +- WARN_ON_ONCE(top == 0); ++ if (err < 0) ++ goto out; + +- lvllist = &tmigr_level_list[top]; ++ if (activate) { ++ struct tmigr_walk data; + + /* +- * Newly created root level should have accounted the upcoming +- * CPU's child group and pre-accounted the old root. ++ * To prevent inconsistent states, active children need to be active in ++ * the new parent as well. Inactive children are already marked inactive ++ * in the parent group: ++ * ++ * * When new groups were created by tmigr_setup_groups() starting from ++ * the lowest level, then they are not active. They will be set active ++ * when the new online CPU comes active. ++ * ++ * * But if new groups above the current top level are required, it is ++ * mandatory to propagate the active state of the already existing ++ * child to the new parents. So tmigr_active_up() activates the ++ * new parents while walking up from the old root to the new. ++ * ++ * * It is ensured that @start is active, as this setup path is ++ * executed in hotplug prepare callback. This is executed by an ++ * already connected and !idle CPU. Even if all other CPUs go idle, ++ * the CPU executing the setup will be responsible up to current top ++ * level group. And the next time it goes inactive, it will release ++ * the new childmask and parent to subsequent walkers through this ++ * @child. Therefore propagate active state unconditionally. + */ +- if (group->num_children == 2 && list_is_singular(lvllist)) { +- /* +- * The target CPU must never do the prepare work, except +- * on early boot when the boot CPU is the target. Otherwise +- * it may spuriously activate the old top level group inside +- * the new one (nevertheless whether old top level group is +- * active or not) and/or release an uninitialized childmask. +- */ +- WARN_ON_ONCE(cpu == raw_smp_processor_id()); +- +- lvllist = &tmigr_level_list[top - 1]; +- list_for_each_entry(child, lvllist, list) { +- if (child->parent) +- continue; ++ WARN_ON_ONCE(!start->parent); ++ data.childmask = start->groupmask; ++ __walk_groups_from(tmigr_active_up, &data, start, start->parent); ++ } + +- tmigr_connect_child_parent(child, group, true); +- } ++ /* Root update */ ++ if (list_is_singular(&tmigr_level_list[top])) { ++ group = list_first_entry(&tmigr_level_list[top], ++ typeof(*group), list); ++ WARN_ON_ONCE(group->parent); ++ if (tmigr_root) { ++ /* Old root should be the same or below */ ++ WARN_ON_ONCE(tmigr_root->level > top); + } ++ tmigr_root = group; + } +- ++out: + kfree(stack); + + return err; +@@ -1741,12 +1750,26 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + + static int tmigr_add_cpu(unsigned int cpu) + { ++ struct tmigr_group *old_root = tmigr_root; + int node = cpu_to_node(cpu); + int ret; + +- mutex_lock(&tmigr_mutex); +- ret = tmigr_setup_groups(cpu, node); +- mutex_unlock(&tmigr_mutex); ++ guard(mutex)(&tmigr_mutex); ++ ++ ret = tmigr_setup_groups(cpu, node, NULL, false); ++ ++ /* Root has changed? Connect the old one to the new */ ++ if (ret >= 0 && old_root && old_root != tmigr_root) { ++ /* ++ * The target CPU must never do the prepare work, except ++ * on early boot when the boot CPU is the target. Otherwise ++ * it may spuriously activate the old top level group inside ++ * the new one (nevertheless whether old top level group is ++ * active or not) and/or release an uninitialized childmask. ++ */ ++ WARN_ON_ONCE(cpu == raw_smp_processor_id()); ++ ret = tmigr_setup_groups(-1, old_root->numa_node, old_root, true); ++ } + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.17/timers-migration-remove-locking-on-group-connection.patch b/queue-6.17/timers-migration-remove-locking-on-group-connection.patch new file mode 100644 index 0000000000..605827a715 --- /dev/null +++ b/queue-6.17/timers-migration-remove-locking-on-group-connection.patch @@ -0,0 +1,93 @@ +From c9ec683ebded5534b3fab7e46e916c594d02f663 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:32 +0200 +Subject: timers/migration: Remove locking on group connection + +From: Frederic Weisbecker + +[ Upstream commit fa9620355d4192200f15cb3d97c6eb9c02442249 ] + +Initializing the tmc's group, the group's number of children and the +group's parent can all be done without locking because: + + 1) Reading the group's parent and its group mask is done locklessly. + + 2) The connections prepared for a given CPU hierarchy are visible to the + target CPU once online, thanks to the CPU hotplug enforced memory + ordering. + + 3) In case of a newly created upper level, the new root and its + connections and initialization are made visible by the CPU which made + the connections. When that CPUs goes idle in the future, the new link + is published by tmigr_inactive_up() through the atomic RmW on + ->migr_state. + + 4) If CPUs were still walking up the active hierarchy, they could observe + the new root earlier. In this case the ordering is enforced by an + early initialization of the group mask and by barriers that maintain + address dependency as explained in: + + b729cc1ec21a ("timers/migration: Fix another race between hotplug and idle entry/exit") + de3ced72a792 ("timers/migration: Enforce group initialization visibility to tree walkers") + + 5) Timers are propagated by a chain of group locking from the bottom to + the top. And while doing so, the tree also propagates groups links + and initialization. Therefore remote expiration, which also relies + on group locking, will observe those links and initialization while + holding the root lock before walking the tree remotely and update + remote timers. This is especially important for migrators in the + active hierarchy that may observe the new root early. + +Therefore the locking is unnecessary at initialization. If anything, it +just brings confusion. Remove it. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-3-frederic@kernel.org +Stable-dep-of: 5eb579dfd46b ("timers/migration: Fix imbalanced NUMA trees") +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index 1e371f1fdc86c..5f8aef94ca0f7 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -1573,9 +1573,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + { + struct tmigr_walk data; + +- raw_spin_lock_irq(&child->lock); +- raw_spin_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING); +- + if (activate) { + /* + * @child is the old top and @parent the new one. In this +@@ -1596,9 +1593,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + */ + smp_store_release(&child->parent, parent); + +- raw_spin_unlock(&parent->lock); +- raw_spin_unlock_irq(&child->lock); +- + trace_tmigr_connect_child_parent(child); + + if (!activate) +@@ -1695,13 +1689,9 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + if (i == 0) { + struct tmigr_cpu *tmc = per_cpu_ptr(&tmigr_cpu, cpu); + +- raw_spin_lock_irq(&group->lock); +- + tmc->tmgroup = group; + tmc->groupmask = BIT(group->num_children++); + +- raw_spin_unlock_irq(&group->lock); +- + trace_tmigr_connect_cpu_parent(tmc); + + /* There are no children that need to be connected */ +-- +2.51.0 + diff --git a/queue-6.17/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch b/queue-6.17/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch new file mode 100644 index 0000000000..841af2831d --- /dev/null +++ b/queue-6.17/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch @@ -0,0 +1,43 @@ +From dadf3334c1f392c1279c49a2812a81a39993dd11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:51 +0200 +Subject: tools/nolibc/dirent: avoid errno in readdir_r +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit 4ada5679f18dbbe92d87c37a842c3368e6ab5e4a ] + +Using errno is not possible when NOLIBC_IGNORE_ERRNO is set. Use +sys_lseek instead of lseek as that avoids using errno. + +Fixes: 665fa8dea90d ("tools/nolibc: add support for directory access") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/dirent.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h +index 758b95c48e7a4..61a122a60327d 100644 +--- a/tools/include/nolibc/dirent.h ++++ b/tools/include/nolibc/dirent.h +@@ -86,9 +86,9 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) + * readdir() can only return one entry at a time. + * Make sure the non-returned ones are not skipped. + */ +- ret = lseek(fd, ldir->d_off, SEEK_SET); +- if (ret == -1) +- return errno; ++ ret = sys_lseek(fd, ldir->d_off, SEEK_SET); ++ if (ret < 0) ++ return -ret; + + entry->d_ino = ldir->d_ino; + /* the destination should always be big enough */ +-- +2.51.0 + diff --git a/queue-6.17/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch b/queue-6.17/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch new file mode 100644 index 0000000000..a1597d1378 --- /dev/null +++ b/queue-6.17/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch @@ -0,0 +1,66 @@ +From f379acf4097961614c22b4fa7c9ccbf13161bab4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 16:26:58 +0200 +Subject: tools/nolibc: handle NULL wstatus argument to waitpid() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 812f223fe9be03dc22abb85240b6f075135d2386 ] + +wstatus is allowed to be NULL. Avoid a segmentation fault in this case. + +Fixes: 0c89abf5ab3f ("tools/nolibc: implement waitpid() in terms of waitid()") +Signed-off-by: Thomas Weißschuh +Acked-by: Willy Tarreau +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/sys/wait.h | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/tools/include/nolibc/sys/wait.h b/tools/include/nolibc/sys/wait.h +index 56ddb806da7f2..c1b797c234d11 100644 +--- a/tools/include/nolibc/sys/wait.h ++++ b/tools/include/nolibc/sys/wait.h +@@ -82,23 +82,29 @@ pid_t waitpid(pid_t pid, int *status, int options) + + switch (info.si_code) { + case 0: +- *status = 0; ++ if (status) ++ *status = 0; + break; + case CLD_EXITED: +- *status = (info.si_status & 0xff) << 8; ++ if (status) ++ *status = (info.si_status & 0xff) << 8; + break; + case CLD_KILLED: +- *status = info.si_status & 0x7f; ++ if (status) ++ *status = info.si_status & 0x7f; + break; + case CLD_DUMPED: +- *status = (info.si_status & 0x7f) | 0x80; ++ if (status) ++ *status = (info.si_status & 0x7f) | 0x80; + break; + case CLD_STOPPED: + case CLD_TRAPPED: +- *status = (info.si_status << 8) + 0x7f; ++ if (status) ++ *status = (info.si_status << 8) + 0x7f; + break; + case CLD_CONTINUED: +- *status = 0xffff; ++ if (status) ++ *status = 0xffff; + break; + default: + return -1; +-- +2.51.0 + diff --git a/queue-6.17/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch b/queue-6.17/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch new file mode 100644 index 0000000000..0549b29758 --- /dev/null +++ b/queue-6.17/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch @@ -0,0 +1,43 @@ +From a9eeaf5e11e7e2b2aaba6148721d2ed20493a1cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:50 +0200 +Subject: tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit c485ca3aff2442adea4c08ceb5183e671ebed22a ] + +There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, +simply print the message with "unknown error" rather than the integer +value of errno. + +Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/stdio.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h +index 7630234408c58..724d05ce69624 100644 +--- a/tools/include/nolibc/stdio.h ++++ b/tools/include/nolibc/stdio.h +@@ -600,7 +600,11 @@ int sscanf(const char *str, const char *format, ...) + static __attribute__((unused)) + void perror(const char *msg) + { ++#ifdef NOLIBC_IGNORE_ERRNO ++ fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); ++#else + fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); ++#endif + } + + static __attribute__((unused)) +-- +2.51.0 + diff --git a/queue-6.17/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch b/queue-6.17/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch new file mode 100644 index 0000000000..1983b81ebf --- /dev/null +++ b/queue-6.17/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch @@ -0,0 +1,77 @@ +From ef7679388b9b6b2edaebdcaca933e07da88701e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 18:41:38 -0300 +Subject: tools/power turbostat: Regression fix Uncore MHz printed in hex + +From: Len Brown + +[ Upstream commit 92664f2e6ab2228a3330734fc72dabeaf8a49ee1 ] + +A patch to allow specifying FORMAT_AVERAGE to added counters... +broke the internally added counter for Cluster Uncore MHz -- printing it in HEX. + +Fixes: dcd1c379b0f1 ("tools/power turbostat: add format "average" for external attributes") +Reported-by: Andrej Tkalcec +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index 931bad99277fe..405b13b690ba5 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -3285,13 +3285,13 @@ int format_counters(PER_THREAD_PARAMS) + + /* Added counters */ + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)t->counter[i]); + else + outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]); +- } else if (mp->format == FORMAT_DELTA) { ++ } else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) { + if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns) + outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]); + else +@@ -3382,13 +3382,13 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->core_throt_cnt); + + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)c->counter[i]); + else + outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]); +- } else if (mp->format == FORMAT_DELTA) { ++ } else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) { + if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns) + outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]); + else +@@ -3581,7 +3581,7 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->uncore_mhz); + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)p->counter[i]); +@@ -3758,7 +3758,7 @@ int delta_package(struct pkg_data *new, struct pkg_data *old) + new->rapl_dram_perf_status.raw_value - old->rapl_dram_perf_status.raw_value; + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) ++ if (mp->format == FORMAT_RAW) + old->counter[i] = new->counter[i]; + else if (mp->format == FORMAT_AVERAGE) + old->counter[i] = new->counter[i]; +-- +2.51.0 + diff --git a/queue-6.17/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch b/queue-6.17/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch new file mode 100644 index 0000000000..7a50b769b5 --- /dev/null +++ b/queue-6.17/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch @@ -0,0 +1,45 @@ +From 785ddf4e9b9093d91ce12dd25610576a15f51a01 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 18:13:48 -0400 +Subject: tracefs: fix a leak in eventfs_create_events_dir() + +From: Al Viro + +[ Upstream commit 798a401660a151633cb171738a72a8f1efb9b0b4 ] + +If we have LOCKDOWN_TRACEFS, the function bails out - *after* +having locked the parent directory and without bothering to +undo that. Just check it before tracefs_start_creating()... + +Fixes: e24709454c45 "tracefs/eventfs: Add missing lockdown checks" +Acked-by: Steven Rostedt (Google) +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/tracefs/event_inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index 8705c77a9e75a..93c231601c8e2 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -757,7 +757,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + const struct eventfs_entry *entries, + int size, void *data) + { +- struct dentry *dentry = tracefs_start_creating(name, parent); ++ struct dentry *dentry; + struct eventfs_root_inode *rei; + struct eventfs_inode *ei; + struct tracefs_inode *ti; +@@ -768,6 +768,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + ++ dentry = tracefs_start_creating(name, parent); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + +-- +2.51.0 + diff --git a/queue-6.17/tty-introduce-tty_port_tty-guard.patch b/queue-6.17/tty-introduce-tty_port_tty-guard.patch new file mode 100644 index 0000000000..3cd3e27383 --- /dev/null +++ b/queue-6.17/tty-introduce-tty_port_tty-guard.patch @@ -0,0 +1,54 @@ +From edf74726606a3b66a7af87754d76665a1d5bea73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 09:24:42 +0200 +Subject: tty: introduce tty_port_tty guard() + +From: Jiri Slaby (SUSE) + +[ Upstream commit e8398b8aed50382c21fcec77e80a5314e7c45c25 ] + +Having this, guards like these work: + scoped_guard(tty_port_tty, port) + tty_wakeup(scoped_tty()); + +See e.g. "tty_port: use scoped_guard()" later in this series. + +The definitions depend on CONFIG_TTY. It's due to tty_kref_put(). +On !CONFIG_TTY, it is an inline and its declaration would conflict. The +guards are not needed in that case, of course. + +Signed-off-by: "Jiri Slaby (SUSE)" +Link: https://lore.kernel.org/r/20250814072456.182853-3-jirislaby@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: d55f3d2375ce ("tty: serial: imx: Only configure the wake register when device is set as wakeup source") +Signed-off-by: Sasha Levin +--- + include/linux/tty_port.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/include/linux/tty_port.h b/include/linux/tty_port.h +index 332ddb93603ec..660c254f1efe5 100644 +--- a/include/linux/tty_port.h ++++ b/include/linux/tty_port.h +@@ -270,4 +270,18 @@ static inline void tty_port_tty_vhangup(struct tty_port *port) + __tty_port_tty_hangup(port, false, false); + } + ++#ifdef CONFIG_TTY ++void tty_kref_put(struct tty_struct *tty); ++__DEFINE_CLASS_IS_CONDITIONAL(tty_port_tty, true); ++__DEFINE_UNLOCK_GUARD(tty_port_tty, struct tty_struct, tty_kref_put(_T->lock)); ++static inline class_tty_port_tty_t class_tty_port_tty_constructor(struct tty_port *tport) ++{ ++ class_tty_port_tty_t _t = { ++ .lock = tty_port_tty_get(tport), ++ }; ++ return _t; ++} ++#define scoped_tty() ((struct tty_struct *)(__guard_ptr(tty_port_tty)(&scope))) ++#endif ++ + #endif +-- +2.51.0 + diff --git a/queue-6.17/tty-serial-imx-only-configure-the-wake-register-when.patch b/queue-6.17/tty-serial-imx-only-configure-the-wake-register-when.patch new file mode 100644 index 0000000000..4599edeaf8 --- /dev/null +++ b/queue-6.17/tty-serial-imx-only-configure-the-wake-register-when.patch @@ -0,0 +1,56 @@ +From 6a06c4f402163ca52506833013ff585b86bc3001 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 12:52:58 +0800 +Subject: tty: serial: imx: Only configure the wake register when device is set + as wakeup source + +From: Sherry Sun + +[ Upstream commit d55f3d2375ceeb08330d30f1e08196993c0b6583 ] + +Currently, the i.MX UART driver enables wake-related registers for all +UART devices by default. However, this is unnecessary for devices that +are not configured as wakeup sources. To address this, add a +device_may_wakeup() check before configuring the UART wake-related +registers. + +Fixes: db1a9b55004c ("tty: serial: imx: Allow UART to be a source for wakeup") +Signed-off-by: Sherry Sun +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20251002045259.2725461-2-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/imx.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index 500dfc009d03e..90e2ea1e8afe5 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -2697,8 +2697,22 @@ static void imx_uart_save_context(struct imx_port *sport) + /* called with irq off */ + static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) + { ++ struct tty_port *port = &sport->port.state->port; ++ struct device *tty_dev; ++ bool may_wake = false; + u32 ucr3; + ++ scoped_guard(tty_port_tty, port) { ++ struct tty_struct *tty = scoped_tty(); ++ ++ tty_dev = tty->dev; ++ may_wake = tty_dev && device_may_wakeup(tty_dev); ++ } ++ ++ /* only configure the wake register when device set as wakeup source */ ++ if (!may_wake) ++ return; ++ + uart_port_lock_irq(&sport->port); + + ucr3 = imx_uart_readl(sport, UCR3); +-- +2.51.0 + diff --git a/queue-6.17/ublk-prevent-invalid-access-with-debug.patch b/queue-6.17/ublk-prevent-invalid-access-with-debug.patch new file mode 100644 index 0000000000..7cfa37ddf2 --- /dev/null +++ b/queue-6.17/ublk-prevent-invalid-access-with-debug.patch @@ -0,0 +1,57 @@ +From 3b62f1a1afc689e8c0a0634dd8a3e1f7ed14b0aa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 12:48:35 +0000 +Subject: ublk: prevent invalid access with DEBUG + +From: Kevin Brodsky + +[ Upstream commit c6a45ee7607de3a350008630f4369b1b5ac80884 ] + +ublk_ch_uring_cmd_local() may jump to the out label before +initialising the io pointer. This will cause trouble if DEBUG is +defined, because the pr_devel() call dereferences io. Clang reports: + +drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] + 2403 | if (tag >= ub->dev_info.queue_depth) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here + 2492 | __func__, cmd_op, tag, ret, io->flags); + | + +Fix this by initialising io to NULL and checking it before +dereferencing it. + +Signed-off-by: Kevin Brodsky +Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") +Reviewed-by: Caleb Sander Mateos +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index 67d4a867aec48..c12bee92fcfd2 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -2340,7 +2340,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + u16 buf_idx = UBLK_INVALID_BUF_IDX; + struct ublk_device *ub = cmd->file->private_data; + struct ublk_queue *ubq; +- struct ublk_io *io; ++ struct ublk_io *io = NULL; + u32 cmd_op = cmd->cmd_op; + unsigned tag = ub_cmd->tag; + struct request *req; +@@ -2458,7 +2458,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + + out: + pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", +- __func__, cmd_op, tag, ret, io->flags); ++ __func__, cmd_op, tag, ret, io ? io->flags : 0); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.17/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-6.17/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..b5ac7372fb --- /dev/null +++ b/queue-6.17/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From 55f40b58a57bc7b2f5da106445de621929300cee Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 81454c3e2484c..338dd2aaabc87 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-6.17/um-don-t-rename-vmap-to-kernel_vmap.patch b/queue-6.17/um-don-t-rename-vmap-to-kernel_vmap.patch new file mode 100644 index 0000000000..3a71e1e098 --- /dev/null +++ b/queue-6.17/um-don-t-rename-vmap-to-kernel_vmap.patch @@ -0,0 +1,70 @@ +From 14091cb7c9e4f2b77deefe4d68a3d803e770ffa8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 16:32:12 +0800 +Subject: um: Don't rename vmap to kernel_vmap + +From: David Gow + +[ Upstream commit a74b6c0e53a6df8e8a096b50c06c4f872906368a ] + +In order to work around the existence of a vmap symbol in libpcap, the +UML makefile unconditionally redefines vmap to kernel_vmap. However, +this not only affects the actual vmap symbol, but also anything else +named vmap, including a number of struct members in DRM. + +This would not be too much of a problem, since all uses are also +updated, except we now have Rust DRM bindings, which expect the +corresponding Rust structs to have 'vmap' names. Since the redefinition +applies in bindgen, but not to Rust code, we end up with errors such as: + +error[E0560]: struct `drm_gem_object_funcs` has no fields named `vmap` + --> rust/kernel/drm/gem/mod.rs:210:9 + +Since libpcap support was removed in commit 12b8e7e69aa7 ("um: Remove +obsolete pcap driver"), remove the, now unnecessary, define as well. + +We also take this opportunity to update the comment. + +Signed-off-by: David Gow +Acked-by: Miguel Ojeda +Link: https://patch.msgid.link/20251122083213.3996586-1-davidgow@google.com +Fixes: 12b8e7e69aa7 ("um: Remove obsolete pcap driver") +[adjust commmit message a bit] +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/Makefile | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/arch/um/Makefile b/arch/um/Makefile +index 7be0143b5ba35..721b652ffb658 100644 +--- a/arch/um/Makefile ++++ b/arch/um/Makefile +@@ -46,19 +46,17 @@ ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) + ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared + KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um + +-# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so +-# named - it's a common symbol in libpcap, so we get a binary which crashes. +-# +-# Same things for in6addr_loopback and mktime - found in libc. For these two we +-# only get link-time error, luckily. ++# -Dstrrchr=kernel_strrchr (as well as the various in6addr symbols) prevents ++# anything from referencing ++# libc symbols with the same name, which can cause a linker error. + # + # -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a + # embedded copy of longjmp, same thing for setjmp. + # +-# These apply to USER_CFLAGS to. ++# These apply to USER_CFLAGS too. + + KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ +- $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ ++ $(ARCH_INCLUDE) $(MODE_INCLUDE) \ + -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ + -Din6addr_loopback=kernel_in6addr_loopback \ + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr \ +-- +2.51.0 + diff --git a/queue-6.17/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-6.17/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..b6c3805b2a --- /dev/null +++ b/queue-6.17/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From 062cc2bcbc44c5359cb4e3889f90e0063d38cda4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 225863321dc47..45cff32656c6e 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-6.17/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-6.17/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..15a722b213 --- /dev/null +++ b/queue-6.17/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From 2b13fb5362b96e2946a941d045ff106ee18c6e2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 3f83ecc9fc236..b07bdf16326a4 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-6.17/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-6.17/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..c437ad9872 --- /dev/null +++ b/queue-6.17/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From 4fd3a22ed0723e399b7f75d5e27bacb3fb03d18b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index b07bdf16326a4..ef0d730770347 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -728,6 +732,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-6.17/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-6.17/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..b978e4748d --- /dev/null +++ b/queue-6.17/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From a92dcce310ad7158625b46b2556be0c26c66a1b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index d2b2787be4092..6138468c67c47 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2431,7 +2431,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-6.17/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-6.17/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..fac8540c15 --- /dev/null +++ b/queue-6.17/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 193b92788f66c34f9b0712b5795a801a0420c27c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index b71680c58de6c..46f343ba48b3d 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-6.17/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch b/queue-6.17/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch new file mode 100644 index 0000000000..7b68e63d4b --- /dev/null +++ b/queue-6.17/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch @@ -0,0 +1,49 @@ +From 30600841db35928efa66834550678f83687a0127 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 06:42:53 -0700 +Subject: vdpa/mlx5: Fix incorrect error code reporting in query_virtqueues + +From: Alok Tiwari + +[ Upstream commit f0ea2e91093ac979d07ebd033e0f45869b1d2608 ] + +When query_virtqueues() fails, the error log prints the variable err +instead of cmd->err. Since err may still be zero at this point, the +log message can misleadingly report a success value 0 even though the +command actually failed. + +Even worse, once err is set to the first failure, subsequent logs +print that same stale value. This makes the error reporting appear +one step behind the actual failing queue index, which is confusing +and misleading. + +Fix the log to report cmd->err, which reflects the real failure code +returned by the firmware. + +Fixes: 1fcdf43ea69e ("vdpa/mlx5: Use async API for vq query command") +Signed-off-by: Alok Tiwari +Acked-by: Jason Wang +Reviewed-by: Dragos Tatulea +Signed-off-by: Michael S. Tsirkin +Message-Id: <20250929134258.80956-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index 53cc9ef01e9f7..ab626f7c81172 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -1256,7 +1256,7 @@ static int query_virtqueues(struct mlx5_vdpa_net *ndev, + int vq_idx = start_vq + i; + + if (cmd->err) { +- mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, err); ++ mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, cmd->err); + if (!err) + err = cmd->err; + continue; +-- +2.51.0 + diff --git a/queue-6.17/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch b/queue-6.17/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch new file mode 100644 index 0000000000..6d5b297dd6 --- /dev/null +++ b/queue-6.17/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch @@ -0,0 +1,40 @@ +From a858fa32d8935f8ed2469f1b033727c4b76e9b09 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 10:46:46 -0700 +Subject: vdpa/pds: use %pe for ERR_PTR() in event handler registration + +From: Alok Tiwari + +[ Upstream commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 ] + +Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended +for string pointers, while %pe correctly prints symbolic error names +for error pointers returned via ERR_PTR(). +This shows the returned error value more clearly. + +Fixes: 67f27b8b3a34 ("pds_vdpa: subscribe to the pds_core events") +Signed-off-by: Alok Tiwari +Reviewed-by: Brett Creeley +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251018174705.1511982-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/pds/vdpa_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c +index 301d95e085960..a1eff7441450c 100644 +--- a/drivers/vdpa/pds/vdpa_dev.c ++++ b/drivers/vdpa/pds/vdpa_dev.c +@@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) + err = pdsc_register_notify(nb); + if (err) { + nb->notifier_call = NULL; +- dev_err(dev, "failed to register pds event handler: %ps\n", ++ dev_err(dev, "failed to register pds event handler: %pe\n", + ERR_PTR(err)); + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.17/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch b/queue-6.17/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch new file mode 100644 index 0000000000..68d960d54e --- /dev/null +++ b/queue-6.17/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch @@ -0,0 +1,305 @@ +From fb5ef79bc9054b038ec7776fbbe1cee15e4d5da7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:36:22 -0700 +Subject: vfio/pci: Use RCU for error/request triggers to avoid circular + locking + +From: Alex Williamson + +[ Upstream commit 98693e0897f754e3f51ce6626ed5f785f625ba2b ] + +Thanks to a device generating an ACS violation during bus reset, +lockdep reported the following circular locking issue: + +CPU0: SET_IRQS (MSI/X): holds igate, acquires memory_lock +CPU1: HOT_RESET: holds memory_lock, acquires pci_bus_sem +CPU2: AER: holds pci_bus_sem, acquires igate + +This results in a potential 3-way deadlock. + +Remove the pci_bus_sem->igate leg of the triangle by using RCU +to peek at the eventfd rather than locking it with igate. + +Fixes: 3be3a074cf5b ("vfio-pci: Don't use device_lock around AER interrupt setup") +Signed-off-by: Alex Williamson +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20251124223623.2770706-1-alex@shazbot.org +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci_core.c | 68 ++++++++++++++++++++++--------- + drivers/vfio/pci/vfio_pci_intrs.c | 52 ++++++++++++++--------- + drivers/vfio/pci/vfio_pci_priv.h | 4 ++ + include/linux/vfio_pci_core.h | 10 ++++- + 4 files changed, 93 insertions(+), 41 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c +index 7dcf5439dedc9..5efe7535f41ed 100644 +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -41,6 +41,40 @@ static bool nointxmask; + static bool disable_vga; + static bool disable_idle_d3; + ++static void vfio_pci_eventfd_rcu_free(struct rcu_head *rcu) ++{ ++ struct vfio_pci_eventfd *eventfd = ++ container_of(rcu, struct vfio_pci_eventfd, rcu); ++ ++ eventfd_ctx_put(eventfd->ctx); ++ kfree(eventfd); ++} ++ ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx) ++{ ++ struct vfio_pci_eventfd *new = NULL; ++ struct vfio_pci_eventfd *old; ++ ++ lockdep_assert_held(&vdev->igate); ++ ++ if (ctx) { ++ new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); ++ if (!new) ++ return -ENOMEM; ++ ++ new->ctx = ctx; ++ } ++ ++ old = rcu_replace_pointer(*peventfd, new, ++ lockdep_is_held(&vdev->igate)); ++ if (old) ++ call_rcu(&old->rcu, vfio_pci_eventfd_rcu_free); ++ ++ return 0; ++} ++ + /* List of PF's that vfio_pci_core_sriov_configure() has been called on */ + static DEFINE_MUTEX(vfio_pci_sriov_pfs_mutex); + static LIST_HEAD(vfio_pci_sriov_pfs); +@@ -696,14 +730,8 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) + vfio_pci_core_disable(vdev); + + mutex_lock(&vdev->igate); +- if (vdev->err_trigger) { +- eventfd_ctx_put(vdev->err_trigger); +- vdev->err_trigger = NULL; +- } +- if (vdev->req_trigger) { +- eventfd_ctx_put(vdev->req_trigger); +- vdev->req_trigger = NULL; +- } ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->err_trigger, NULL); ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->req_trigger, NULL); + mutex_unlock(&vdev->igate); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_close_device); +@@ -1800,21 +1828,21 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count) + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + struct pci_dev *pdev = vdev->pdev; ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->req_trigger) { ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->req_trigger); ++ if (eventfd) { + if (!(count % 10)) + pci_notice_ratelimited(pdev, + "Relaying device request to user (#%u)\n", + count); +- eventfd_signal(vdev->req_trigger); ++ eventfd_signal(eventfd->ctx); + } else if (count == 0) { + pci_warn(pdev, + "No device request channel registered, blocked until released by user\n"); + } +- +- mutex_unlock(&vdev->igate); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_request); + +@@ -2227,13 +2255,13 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) + { + struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->err_trigger) +- eventfd_signal(vdev->err_trigger); +- +- mutex_unlock(&vdev->igate); ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->err_trigger); ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ rcu_read_unlock(); + + return PCI_ERS_RESULT_CAN_RECOVER; + } +diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c +index 61d29f6b3730c..969e9342f9b1f 100644 +--- a/drivers/vfio/pci/vfio_pci_intrs.c ++++ b/drivers/vfio/pci/vfio_pci_intrs.c +@@ -731,21 +731,27 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_core_device *vdev, + return 0; + } + +-static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, ++static int vfio_pci_set_ctx_trigger_single(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, + unsigned int count, uint32_t flags, + void *data) + { + /* DATA_NONE/DATA_BOOL enables loopback testing */ + if (flags & VFIO_IRQ_SET_DATA_NONE) { +- if (*ctx) { +- if (count) { +- eventfd_signal(*ctx); +- } else { +- eventfd_ctx_put(*ctx); +- *ctx = NULL; +- } ++ struct vfio_pci_eventfd *eventfd; ++ ++ eventfd = rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (!eventfd) ++ return -EINVAL; ++ ++ if (count) { ++ eventfd_signal(eventfd->ctx); + return 0; + } ++ ++ return vfio_pci_eventfd_replace_locked(vdev, peventfd, NULL); + } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { + uint8_t trigger; + +@@ -753,8 +759,15 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + return -EINVAL; + + trigger = *(uint8_t *)data; +- if (trigger && *ctx) +- eventfd_signal(*ctx); ++ ++ if (trigger) { ++ struct vfio_pci_eventfd *eventfd = ++ rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ } + + return 0; + } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { +@@ -765,22 +778,23 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + + fd = *(int32_t *)data; + if (fd == -1) { +- if (*ctx) +- eventfd_ctx_put(*ctx); +- *ctx = NULL; ++ return vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, NULL); + } else if (fd >= 0) { + struct eventfd_ctx *efdctx; ++ int ret; + + efdctx = eventfd_ctx_fdget(fd); + if (IS_ERR(efdctx)) + return PTR_ERR(efdctx); + +- if (*ctx) +- eventfd_ctx_put(*ctx); ++ ret = vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, efdctx); ++ if (ret) ++ eventfd_ctx_put(efdctx); + +- *ctx = efdctx; ++ return ret; + } +- return 0; + } + + return -EINVAL; +@@ -793,7 +807,7 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_ERR_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->err_trigger, + count, flags, data); + } + +@@ -804,7 +818,7 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->req_trigger, + count, flags, data); + } + +diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h +index a9972eacb2936..97d992c063229 100644 +--- a/drivers/vfio/pci/vfio_pci_priv.h ++++ b/drivers/vfio/pci/vfio_pci_priv.h +@@ -26,6 +26,10 @@ struct vfio_pci_ioeventfd { + bool vfio_pci_intx_mask(struct vfio_pci_core_device *vdev); + void vfio_pci_intx_unmask(struct vfio_pci_core_device *vdev); + ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx); ++ + int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags, + unsigned index, unsigned start, unsigned count, + void *data); +diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h +index f541044e42a2a..f5c93787f8e0b 100644 +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,6 +28,11 @@ + struct vfio_pci_core_device; + struct vfio_pci_region; + ++struct vfio_pci_eventfd { ++ struct eventfd_ctx *ctx; ++ struct rcu_head rcu; ++}; ++ + struct vfio_pci_regops { + ssize_t (*rw)(struct vfio_pci_core_device *vdev, char __user *buf, + size_t count, loff_t *ppos, bool iswrite); +@@ -83,8 +89,8 @@ struct vfio_pci_core_device { + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; + int ioeventfds_nr; +- struct eventfd_ctx *err_trigger; +- struct eventfd_ctx *req_trigger; ++ struct vfio_pci_eventfd __rcu *err_trigger; ++ struct vfio_pci_eventfd __rcu *req_trigger; + struct eventfd_ctx *pm_wake_eventfd_ctx; + struct list_head dummy_resources_list; + struct mutex ioeventfds_lock; +-- +2.51.0 + diff --git a/queue-6.17/vhost-fix-kthread-worker-cgroup-failure-handling.patch b/queue-6.17/vhost-fix-kthread-worker-cgroup-failure-handling.patch new file mode 100644 index 0000000000..419682032b --- /dev/null +++ b/queue-6.17/vhost-fix-kthread-worker-cgroup-failure-handling.patch @@ -0,0 +1,45 @@ +From af321b3b62817e0b9435c119305eeecd3eb41c96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 14:43:58 -0500 +Subject: vhost: Fix kthread worker cgroup failure handling + +From: Mike Christie + +[ Upstream commit f3f64c2eaffbc3169bbe1e5d1e897e6dacc839d1 ] + +If we fail to attach to a cgroup we are leaking the id. This adds +a new goto to free the id. + +Fixes: 7d9896e9f6d0 ("vhost: Reintroduce kthread API and add mode selection") +Signed-off-by: Mike Christie +Acked-by: Jason Wang +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251101194358.13605-1-michael.christie@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vhost/vhost.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index a78226b37739d..bccdc9eab267a 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -804,11 +804,13 @@ static int vhost_kthread_worker_create(struct vhost_worker *worker, + + ret = vhost_attach_task_to_cgroups(worker); + if (ret) +- goto stop_worker; ++ goto free_id; + + worker->id = id; + return 0; + ++free_id: ++ xa_erase(&dev->worker_xa, id); + stop_worker: + vhost_kthread_do_stop(worker); + return ret; +-- +2.51.0 + diff --git a/queue-6.17/virtio-clean-up-features-qword-dword-terms.patch b/queue-6.17/virtio-clean-up-features-qword-dword-terms.patch new file mode 100644 index 0000000000..e1f20b8a89 --- /dev/null +++ b/queue-6.17/virtio-clean-up-features-qword-dword-terms.patch @@ -0,0 +1,376 @@ +From 1e36fd6a816b0f7d45cff5726ea76fb8cb84b987 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 10:56:57 -0400 +Subject: virtio: clean up features qword/dword terms + +From: Michael S. Tsirkin + +[ Upstream commit 9513f25056b22100ddffe24898c587873b0d022c ] + +virtio pci uses word to mean "16 bits". mmio uses it to mean +"32 bits". + +To avoid confusion, let's avoid the term in core virtio +altogether. Just say U64 to mean "64 bit". + +Fixes: e7d4c1c5a546 ("virtio: introduce extended features") +Cc: Paolo Abeni +Acked-by: Jason Wang +Message-ID: +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vhost/net.c | 12 +++++------ + drivers/virtio/virtio.c | 12 +++++------ + drivers/virtio/virtio_debug.c | 10 ++++----- + drivers/virtio/virtio_pci_modern_dev.c | 6 +++--- + include/linux/virtio.h | 2 +- + include/linux/virtio_config.h | 2 +- + include/linux/virtio_features.h | 29 +++++++++++++------------- + include/linux/virtio_pci_modern.h | 8 +++---- + 8 files changed, 41 insertions(+), 40 deletions(-) + +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 8f7f50acb6d63..1e77c0482b849 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -69,7 +69,7 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" + + #define VHOST_DMA_IS_DONE(len) ((__force u32)(len) >= (__force u32)VHOST_DMA_DONE_LEN) + +-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS] = { ++static const u64 vhost_net_features[VIRTIO_FEATURES_U64S] = { + VHOST_FEATURES | + (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | + (1ULL << VIRTIO_NET_F_MRG_RXBUF) | +@@ -1731,7 +1731,7 @@ static long vhost_net_set_owner(struct vhost_net *n) + static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + unsigned long arg) + { +- u64 all_features[VIRTIO_FEATURES_DWORDS]; ++ u64 all_features[VIRTIO_FEATURES_U64S]; + struct vhost_net *n = f->private_data; + void __user *argp = (void __user *)arg; + u64 __user *featurep = argp; +@@ -1763,7 +1763,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + + /* Copy the net features, up to the user-provided buffer size */ + argp += sizeof(u64); +- copied = min(count, VIRTIO_FEATURES_DWORDS); ++ copied = min(count, (u64)VIRTIO_FEATURES_U64S); + if (copy_to_user(argp, vhost_net_features, + copied * sizeof(u64))) + return -EFAULT; +@@ -1778,13 +1778,13 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + + virtio_features_zero(all_features); + argp += sizeof(u64); +- copied = min(count, VIRTIO_FEATURES_DWORDS); ++ copied = min(count, (u64)VIRTIO_FEATURES_U64S); + if (copy_from_user(all_features, argp, copied * sizeof(u64))) + return -EFAULT; + + /* + * Any feature specified by user-space above +- * VIRTIO_FEATURES_MAX is not supported by definition. ++ * VIRTIO_FEATURES_BITS is not supported by definition. + */ + for (i = copied; i < count; ++i) { + if (copy_from_user(&features, featurep + 1 + i, +@@ -1794,7 +1794,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + return -EOPNOTSUPP; + } + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; i++) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; i++) + if (all_features[i] & ~vhost_net_features[i]) + return -EOPNOTSUPP; + +diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c +index a09eb4d62f82d..5bdc6b82b30b4 100644 +--- a/drivers/virtio/virtio.c ++++ b/drivers/virtio/virtio.c +@@ -53,7 +53,7 @@ static ssize_t features_show(struct device *_d, + + /* We actually represent this as a bitstring, as it could be + * arbitrary length in future. */ +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) + len += sysfs_emit_at(buf, len, "%c", + __virtio_test_bit(dev, i) ? '1' : '0'); + len += sysfs_emit_at(buf, len, "\n"); +@@ -272,8 +272,8 @@ static int virtio_dev_probe(struct device *_d) + int err, i; + struct virtio_device *dev = dev_to_virtio(_d); + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); +- u64 device_features[VIRTIO_FEATURES_DWORDS]; +- u64 driver_features[VIRTIO_FEATURES_DWORDS]; ++ u64 device_features[VIRTIO_FEATURES_U64S]; ++ u64 driver_features[VIRTIO_FEATURES_U64S]; + u64 driver_features_legacy; + + /* We have a driver! */ +@@ -286,7 +286,7 @@ static int virtio_dev_probe(struct device *_d) + virtio_features_zero(driver_features); + for (i = 0; i < drv->feature_table_size; i++) { + unsigned int f = drv->feature_table[i]; +- if (!WARN_ON_ONCE(f >= VIRTIO_FEATURES_MAX)) ++ if (!WARN_ON_ONCE(f >= VIRTIO_FEATURES_BITS)) + virtio_features_set_bit(driver_features, f); + } + +@@ -303,7 +303,7 @@ static int virtio_dev_probe(struct device *_d) + } + + if (virtio_features_test_bit(device_features, VIRTIO_F_VERSION_1)) { +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; ++i) + dev->features_array[i] = driver_features[i] & + device_features[i]; + } else { +@@ -325,7 +325,7 @@ static int virtio_dev_probe(struct device *_d) + goto err; + + if (drv->validate) { +- u64 features[VIRTIO_FEATURES_DWORDS]; ++ u64 features[VIRTIO_FEATURES_U64S]; + + virtio_features_copy(features, dev->features_array); + err = drv->validate(dev); +diff --git a/drivers/virtio/virtio_debug.c b/drivers/virtio/virtio_debug.c +index d58713ddf2e58..ccf1955a1183a 100644 +--- a/drivers/virtio/virtio_debug.c ++++ b/drivers/virtio/virtio_debug.c +@@ -8,12 +8,12 @@ static struct dentry *virtio_debugfs_dir; + + static int virtio_debug_device_features_show(struct seq_file *s, void *data) + { +- u64 device_features[VIRTIO_FEATURES_DWORDS]; ++ u64 device_features[VIRTIO_FEATURES_U64S]; + struct virtio_device *dev = s->private; + unsigned int i; + + virtio_get_features(dev, device_features); +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { + if (virtio_features_test_bit(device_features, i)) + seq_printf(s, "%u\n", i); + } +@@ -26,7 +26,7 @@ static int virtio_debug_filter_features_show(struct seq_file *s, void *data) + struct virtio_device *dev = s->private; + unsigned int i; + +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { + if (virtio_features_test_bit(dev->debugfs_filter_features, i)) + seq_printf(s, "%u\n", i); + } +@@ -50,7 +50,7 @@ static int virtio_debug_filter_feature_add(void *data, u64 val) + { + struct virtio_device *dev = data; + +- if (val >= VIRTIO_FEATURES_MAX) ++ if (val >= VIRTIO_FEATURES_BITS) + return -EINVAL; + + virtio_features_set_bit(dev->debugfs_filter_features, val); +@@ -64,7 +64,7 @@ static int virtio_debug_filter_feature_del(void *data, u64 val) + { + struct virtio_device *dev = data; + +- if (val >= VIRTIO_FEATURES_MAX) ++ if (val >= VIRTIO_FEATURES_BITS) + return -EINVAL; + + virtio_features_clear_bit(dev->debugfs_filter_features, val); +diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c +index 9e503b7a58d81..413a8c3534638 100644 +--- a/drivers/virtio/virtio_pci_modern_dev.c ++++ b/drivers/virtio/virtio_pci_modern_dev.c +@@ -401,7 +401,7 @@ void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev, + int i; + + virtio_features_zero(features); +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u64 cur; + + vp_iowrite32(i, &cfg->device_feature_select); +@@ -427,7 +427,7 @@ vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev, + int i; + + virtio_features_zero(features); +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u64 cur; + + vp_iowrite32(i, &cfg->guest_feature_select); +@@ -448,7 +448,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, + struct virtio_pci_common_cfg __iomem *cfg = mdev->common; + int i; + +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u32 cur = features[i >> 1] >> (32 * (i & 1)); + + vp_iowrite32(i, &cfg->guest_feature_select); +diff --git a/include/linux/virtio.h b/include/linux/virtio.h +index db31fc6f4f1fa..bbeb55f478b5d 100644 +--- a/include/linux/virtio.h ++++ b/include/linux/virtio.h +@@ -166,7 +166,7 @@ struct virtio_device { + void *priv; + #ifdef CONFIG_VIRTIO_DEBUG + struct dentry *debugfs_dir; +- u64 debugfs_filter_features[VIRTIO_FEATURES_DWORDS]; ++ u64 debugfs_filter_features[VIRTIO_FEATURES_U64S]; + #endif + }; + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index ba621d86517c3..7e10fe0105279 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -80,7 +80,7 @@ struct virtqueue_info { + * Returns the first 64 feature bits. + * @get_extended_features: + * vdev: the virtio_device +- * Returns the first VIRTIO_FEATURES_MAX feature bits (all we currently ++ * Returns the first VIRTIO_FEATURES_BITS feature bits (all we currently + * need). + * @finalize_features: confirm what device features we'll be using. + * vdev: the virtio_device +diff --git a/include/linux/virtio_features.h b/include/linux/virtio_features.h +index f748f2f87de8d..ea2ad8717882e 100644 +--- a/include/linux/virtio_features.h ++++ b/include/linux/virtio_features.h +@@ -4,15 +4,16 @@ + + #include + +-#define VIRTIO_FEATURES_DWORDS 2 +-#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_DWORDS * 64) +-#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_DWORDS * 2) ++#define VIRTIO_FEATURES_U64S 2 ++#define VIRTIO_FEATURES_BITS (VIRTIO_FEATURES_U64S * 64) ++ + #define VIRTIO_BIT(b) BIT_ULL((b) & 0x3f) +-#define VIRTIO_DWORD(b) ((b) >> 6) ++#define VIRTIO_U64(b) ((b) >> 6) ++ + #define VIRTIO_DECLARE_FEATURES(name) \ + union { \ + u64 name; \ +- u64 name##_array[VIRTIO_FEATURES_DWORDS];\ ++ u64 name##_array[VIRTIO_FEATURES_U64S];\ + } + + static inline bool virtio_features_chk_bit(unsigned int bit) +@@ -22,9 +23,9 @@ static inline bool virtio_features_chk_bit(unsigned int bit) + * Don't care returning the correct value: the build + * will fail before any bad features access + */ +- BUILD_BUG_ON(bit >= VIRTIO_FEATURES_MAX); ++ BUILD_BUG_ON(bit >= VIRTIO_FEATURES_BITS); + } else { +- if (WARN_ON_ONCE(bit >= VIRTIO_FEATURES_MAX)) ++ if (WARN_ON_ONCE(bit >= VIRTIO_FEATURES_BITS)) + return false; + } + return true; +@@ -34,26 +35,26 @@ static inline bool virtio_features_test_bit(const u64 *features, + unsigned int bit) + { + return virtio_features_chk_bit(bit) && +- !!(features[VIRTIO_DWORD(bit)] & VIRTIO_BIT(bit)); ++ !!(features[VIRTIO_U64(bit)] & VIRTIO_BIT(bit)); + } + + static inline void virtio_features_set_bit(u64 *features, + unsigned int bit) + { + if (virtio_features_chk_bit(bit)) +- features[VIRTIO_DWORD(bit)] |= VIRTIO_BIT(bit); ++ features[VIRTIO_U64(bit)] |= VIRTIO_BIT(bit); + } + + static inline void virtio_features_clear_bit(u64 *features, + unsigned int bit) + { + if (virtio_features_chk_bit(bit)) +- features[VIRTIO_DWORD(bit)] &= ~VIRTIO_BIT(bit); ++ features[VIRTIO_U64(bit)] &= ~VIRTIO_BIT(bit); + } + + static inline void virtio_features_zero(u64 *features) + { +- memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_DWORDS); ++ memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_U64S); + } + + static inline void virtio_features_from_u64(u64 *features, u64 from) +@@ -66,7 +67,7 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) + { + int i; + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; ++i) + if (f1[i] != f2[i]) + return false; + return true; +@@ -74,14 +75,14 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) + + static inline void virtio_features_copy(u64 *to, const u64 *from) + { +- memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_DWORDS); ++ memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_U64S); + } + + static inline void virtio_features_andnot(u64 *to, const u64 *f1, const u64 *f2) + { + int i; + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; i++) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; i++) + to[i] = f1[i] & ~f2[i]; + } + +diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h +index 48bc12d1045bd..9a3f2fc53bd65 100644 +--- a/include/linux/virtio_pci_modern.h ++++ b/include/linux/virtio_pci_modern.h +@@ -107,7 +107,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, + static inline u64 + vp_modern_get_features(struct virtio_pci_modern_device *mdev) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + + vp_modern_get_extended_features(mdev, features_array); + return features_array[0]; +@@ -116,11 +116,11 @@ vp_modern_get_features(struct virtio_pci_modern_device *mdev) + static inline u64 + vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + int i; + + vp_modern_get_driver_extended_features(mdev, features_array); +- for (i = 1; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 1; i < VIRTIO_FEATURES_U64S; ++i) + WARN_ON_ONCE(features_array[i]); + return features_array[0]; + } +@@ -128,7 +128,7 @@ vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) + static inline void + vp_modern_set_features(struct virtio_pci_modern_device *mdev, u64 features) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + + virtio_features_from_u64(features_array, features); + vp_modern_set_extended_features(mdev, features_array); +-- +2.51.0 + diff --git a/queue-6.17/virtio-fix-grammar-in-virtio_queue_info-docs.patch b/queue-6.17/virtio-fix-grammar-in-virtio_queue_info-docs.patch new file mode 100644 index 0000000000..307eaba305 --- /dev/null +++ b/queue-6.17/virtio-fix-grammar-in-virtio_queue_info-docs.patch @@ -0,0 +1,36 @@ +From f47455e351a78fbde1334584a88e7c292a3cd038 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:36 -0500 +Subject: virtio: fix grammar in virtio_queue_info docs + +From: Michael S. Tsirkin + +[ Upstream commit 63598fba55ab9d384818fed48dc04006cecf7be4 ] + +Fix grammar in the description of @ctx + +Fixes: c502eb85c34e ("virtio: introduce virtio_queue_info struct and find_vqs_info() config op") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index f8a00a780a44d..2e7ead07376d1 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -24,7 +24,7 @@ typedef void vq_callback_t(struct virtqueue *); + * a virtqueue unused by the driver. + * @callback: A callback to invoke on a used buffer notification. + * NULL for a virtqueue that does not need a callback. +- * @ctx: A flag to indicate to maintain an extra context per virtqueue. ++ * @ctx: whether to maintain an extra context per virtqueue. + */ + struct virtqueue_info { + const char *name; +-- +2.51.0 + diff --git a/queue-6.17/virtio-fix-typo-in-virtio_device_ready-comment.patch b/queue-6.17/virtio-fix-typo-in-virtio_device_ready-comment.patch new file mode 100644 index 0000000000..d63e8e8989 --- /dev/null +++ b/queue-6.17/virtio-fix-typo-in-virtio_device_ready-comment.patch @@ -0,0 +1,36 @@ +From fa50658810d0c626168a4983afcea685371686f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:31 -0500 +Subject: virtio: fix typo in virtio_device_ready() comment + +From: Michael S. Tsirkin + +[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ] + +"coherenct" -> "coherent" + +Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 7427b79d6f3d5..148dc5056002f 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -290,7 +290,7 @@ void virtio_device_ready(struct virtio_device *dev) + * specific set_status() method. + * + * A well behaved device will only notify a virtqueue after +- * DRIVER_OK, this means the device should "see" the coherenct ++ * DRIVER_OK, this means the device should "see" the coherent + * memory write that set vq->broken as false which is done by + * the driver when it sees DRIVER_OK, then the following + * driver's vring_interrupt() will see vq->broken as false so +-- +2.51.0 + diff --git a/queue-6.17/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-6.17/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..a10bb25c1b --- /dev/null +++ b/queue-6.17/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From e0f93770d57f6709acc89c82a2a8b53150bb52e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 2e7ead07376d1..ba621d86517c3 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -312,7 +312,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu_mask: the cpu mask + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-6.17/virtio-fix-whitespace-in-virtio_config_ops.patch b/queue-6.17/virtio-fix-whitespace-in-virtio_config_ops.patch new file mode 100644 index 0000000000..3b06e9881c --- /dev/null +++ b/queue-6.17/virtio-fix-whitespace-in-virtio_config_ops.patch @@ -0,0 +1,37 @@ +From 59fd936cc14a05f6c7c885f543855f4451bc6e36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:34 -0500 +Subject: virtio: fix whitespace in virtio_config_ops + +From: Michael S. Tsirkin + +[ Upstream commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 ] + +The finalize_features documentation uses a tab between words. +Use space instead. + +Fixes: d16c0cd27331 ("docs: driver-api: virtio: virtio on Linux") +Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com> +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 148dc5056002f..f8a00a780a44d 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -86,7 +86,7 @@ struct virtqueue_info { + * vdev: the virtio_device + * This sends the driver feature bits to the device: it can change + * the dev->feature bits if it wants. +- * Note that despite the name this can be called any number of ++ * Note that despite the name this can be called any number of + * times. + * Returns 0 on success or error status + * @bus_name: return the bus name associated with the device (optional) +-- +2.51.0 + diff --git a/queue-6.17/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-6.17/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..4c24937005 --- /dev/null +++ b/queue-6.17/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From cbf70b18eb97390e2184e18d29c86fd41348e8cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index 657b07a607881..1abecaf764654 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -80,7 +80,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-6.17/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch b/queue-6.17/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch new file mode 100644 index 0000000000..2728c31293 --- /dev/null +++ b/queue-6.17/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch @@ -0,0 +1,51 @@ +From 3d29b8ea2d8d463552dac11949d818f0e6ff5121 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 16:42:20 +0800 +Subject: watchdog: starfive: Fix resource leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 5bcc5786a0cfa9249ccbe539833040a6285d0de3 ] + +If pm_runtime_put_sync() fails after watchdog_register_device() +succeeds, the probe function jumps to err_exit without +unregistering the watchdog device. This leaves the watchdog +registered in the subsystem while the driver fails to load, +resulting in a resource leak. + +Add a new error label err_unregister_wdt to properly unregister +the watchdog device. + +Fixes: 8bc22a2f1bf0 ("watchdog: starfive: Check pm_runtime_enabled() before decrementing usage counter") +Signed-off-by: Haotian Zhang +Reviewed-by: Wim Van Sebroeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/starfive-wdt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c +index 355918d62f63d..ed71d3960a0f2 100644 +--- a/drivers/watchdog/starfive-wdt.c ++++ b/drivers/watchdog/starfive-wdt.c +@@ -500,12 +500,14 @@ static int starfive_wdt_probe(struct platform_device *pdev) + if (pm_runtime_enabled(&pdev->dev)) { + ret = pm_runtime_put_sync(&pdev->dev); + if (ret) +- goto err_exit; ++ goto err_unregister_wdt; + } + } + + return 0; + ++err_unregister_wdt: ++ watchdog_unregister_device(&wdt->wdd); + err_exit: + starfive_wdt_disable_clock(wdt); + pm_runtime_disable(&pdev->dev); +-- +2.51.0 + diff --git a/queue-6.17/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-6.17/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..5ee2199015 --- /dev/null +++ b/queue-6.17/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From ee96eb4aa7ba8fdc83c0175e3a058f1b46c7c6a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 650fdc7996e1c..dd3c2d69c9df1 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -326,19 +326,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); +@@ -355,15 +363,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -385,8 +398,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -417,7 +432,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -425,8 +441,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -443,7 +461,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -460,12 +478,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + static int wdat_wdt_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch b/queue-6.17/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch new file mode 100644 index 0000000000..d36b423489 --- /dev/null +++ b/queue-6.17/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch @@ -0,0 +1,158 @@ +From ce5d9d328751df92476cb3263374d4d8fad55647 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 19:07:57 +0800 +Subject: wifi: ath10k: move recovery check logic into a new work +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kang Yang + +[ Upstream commit f35a07a4842a88801d9182b1a76d178bfa616978 ] + +Currently, ath10k has a recovery check logic. It will wait for the +last recovery to finish by wait_for_completion_timeout(); + +But in SDIO scenarios, the recovery function may be invoked from +interrupt context, where long blocking waits are undesirable and can +lead to system instability. + +Additionally, Linux’s ordered workqueue processes one task at a time. +If a previous recovery is still queued or executing, new triggers are +ignored. This prevents accurate tracking of consecutive failures and +delays transition to the WEDGED state. + +To address this, move the recovery check logic into a different +workqueue. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189 + +Fixes: c256a94d1b1b ("wifi: ath10k: shutdown driver when hardware is unreliable") +Signed-off-by: Kang Yang +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251014110757.155-1-kang.yang@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/core.c | 20 +++++++++----------- + drivers/net/wireless/ath/ath10k/core.h | 2 +- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 3 files changed, 11 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 6f78f1752cd6f..9ae3595fb6986 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -2493,8 +2492,9 @@ static int ath10k_init_hw_params(struct ath10k *ar) + return 0; + } + +-static bool ath10k_core_needs_recovery(struct ath10k *ar) ++static void ath10k_core_recovery_check_work(struct work_struct *work) + { ++ struct ath10k *ar = container_of(work, struct ath10k, recovery_check_work); + long time_left; + + /* Sometimes the recovery will fail and then the next all recovery fail, +@@ -2504,7 +2504,7 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ath10k_err(ar, "consecutive fail %d times, will shutdown driver!", + atomic_read(&ar->fail_cont_count)); + ar->state = ATH10K_STATE_WEDGED; +- return false; ++ return; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "total recovery count: %d", ++ar->recovery_count); +@@ -2518,27 +2518,24 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ATH10K_RECOVERY_TIMEOUT_HZ); + if (time_left) { + ath10k_warn(ar, "previous recovery succeeded, skip this!\n"); +- return false; ++ return; + } + + /* Record the continuous recovery fail count when recovery failed. */ + atomic_inc(&ar->fail_cont_count); + + /* Avoid having multiple recoveries at the same time. */ +- return false; ++ return; + } + + atomic_inc(&ar->pending_recovery); +- +- return true; ++ queue_work(ar->workqueue, &ar->restart_work); + } + + void ath10k_core_start_recovery(struct ath10k *ar) + { +- if (!ath10k_core_needs_recovery(ar)) +- return; +- +- queue_work(ar->workqueue, &ar->restart_work); ++ /* Use workqueue_aux to avoid blocking recovery tracking */ ++ queue_work(ar->workqueue_aux, &ar->recovery_check_work); + } + EXPORT_SYMBOL(ath10k_core_start_recovery); + +@@ -3734,6 +3731,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, + + INIT_WORK(&ar->register_work, ath10k_core_register_work); + INIT_WORK(&ar->restart_work, ath10k_core_restart); ++ INIT_WORK(&ar->recovery_check_work, ath10k_core_recovery_check_work); + INIT_WORK(&ar->set_coverage_class_work, + ath10k_core_set_coverage_class_work); + +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 8c72ed386edb7..859176fcb5a29 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -1208,6 +1207,7 @@ struct ath10k { + + struct work_struct register_work; + struct work_struct restart_work; ++ struct work_struct recovery_check_work; + struct work_struct bundle_tx_work; + struct work_struct tx_complete_work; + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 154ac7a709824..da6f7957a0ae7 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -5428,6 +5427,7 @@ static void ath10k_stop(struct ieee80211_hw *hw, bool suspend) + cancel_work_sync(&ar->set_coverage_class_work); + cancel_delayed_work_sync(&ar->scan.timeout); + cancel_work_sync(&ar->restart_work); ++ cancel_work_sync(&ar->recovery_check_work); + } + + static int ath10k_config_ps(struct ath10k *ar) +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath11k-fix-peer-he-mcs-assignment.patch b/queue-6.17/wifi-ath11k-fix-peer-he-mcs-assignment.patch new file mode 100644 index 0000000000..80023b58d8 --- /dev/null +++ b/queue-6.17/wifi-ath11k-fix-peer-he-mcs-assignment.patch @@ -0,0 +1,94 @@ +From db06221a0fc255c85bd2c17fca56105cf9aa6298 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:49:00 +0800 +Subject: wifi: ath11k: fix peer HE MCS assignment + +From: Baochen Qiang + +[ Upstream commit 4a013ca2d490c73c40588d62712ffaa432046a04 ] + +In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to +firmware as receive MCS while peer's receive MCS sent as transmit MCS, +which goes against firmwire's definition. + +While connecting to a misbehaved AP that advertises 0xffff (meaning not +supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff +is assigned to he_mcs->rx_mcs_set field. + + Ext Tag: HE Capabilities + [...] + Supported HE-MCS and NSS Set + [...] + Rx and Tx MCS Maps 160 MHz + [...] + Tx HE-MCS Map 160 MHz: 0xffff + +Swap the assignment to fix this issue. + +As the HE rate control mask is meant to limit our own transmit MCS, it +needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive MCS. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 49c639d73d58d..f142c17aa9aa7 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2522,10 +2522,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2535,10 +2535,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 649839d243293..110035dae8a61 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -2091,8 +2091,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ /* firmware interprets mcs->rx_mcs_set field as peer's ++ * RX capability ++ */ ++ he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath11k-fix-vht-mcs-assignment.patch b/queue-6.17/wifi-ath11k-fix-vht-mcs-assignment.patch new file mode 100644 index 0000000000..ce3b61498c --- /dev/null +++ b/queue-6.17/wifi-ath11k-fix-vht-mcs-assignment.patch @@ -0,0 +1,102 @@ +From 7281ab32d4471440a005b631b64d12092c5475fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:48:59 +0800 +Subject: wifi: ath11k: fix VHT MCS assignment + +From: Baochen Qiang + +[ Upstream commit 47d0cd6bccb4604192633cc8d29511e85d811fc0 ] + +While associating, firmware needs to know peer's receive capability to +calculate its own VHT transmit MCS, currently host sends this information +to firmware via mcs->rx_mcs_set field, this is wrong as firmware actually +takes it from mcs->tx_mcs_set field. Till now there is no failure seen +due to this, most likely because almost all peers are advertising the +same capability for both transmit and receive. Swap the assignment to +fix it. + +Besides, rate control mask is meant to limit our own transmit MCS, hence +need to go via mcs->tx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive +capability rather than transmit capability. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-1-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 13 ++++++++----- + drivers/net/wireless/ath/ath11k/wmi.h | 2 ++ + 3 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 0e41b5a91d66d..49c639d73d58d 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2235,9 +2235,9 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); + arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); + arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); ++ arg->rx_mcs_set = ath11k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); + arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); +- arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit( +- __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); ++ arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); + + /* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default. + * VHT mcs rate 10 and 11 is not supported in 11ac standard. +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index e3b444333deed..649839d243293 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -2061,10 +2061,13 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; + + if (param->vht_capable) { +- mcs->rx_max_rate = param->rx_max_rate; +- mcs->rx_mcs_set = param->rx_mcs_set; +- mcs->tx_max_rate = param->tx_max_rate; +- mcs->tx_mcs_set = param->tx_mcs_set; ++ /* firmware interprets mcs->tx_mcs_set field as peer's ++ * RX capability ++ */ ++ mcs->tx_max_rate = param->rx_max_rate; ++ mcs->tx_mcs_set = param->rx_mcs_set; ++ mcs->rx_max_rate = param->tx_max_rate; ++ mcs->rx_mcs_set = param->tx_mcs_set; + } + + /* HE Rates */ +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 9fcffaa2f383c..6e9354297e71d 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -4133,8 +4133,10 @@ struct wmi_rate_set { + struct wmi_vht_rate_set { + u32 tlv_header; + u32 rx_max_rate; ++ /* MCS at which the peer can transmit */ + u32 rx_mcs_set; + u32 tx_max_rate; ++ /* MCS at which the peer can receive */ + u32 tx_mcs_set; + u32 tx_max_mcs_nss; + } __packed; +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath11k-restore-register-window-after-global-res.patch b/queue-6.17/wifi-ath11k-restore-register-window-after-global-res.patch new file mode 100644 index 0000000000..2e0f92b86e --- /dev/null +++ b/queue-6.17/wifi-ath11k-restore-register-window-after-global-res.patch @@ -0,0 +1,89 @@ +From 86ce0bc29797bc527638b26e509d4e5ec3f01ed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 10:30:20 +0800 +Subject: wifi: ath11k: restore register window after global reset + +From: Baochen Qiang + +[ Upstream commit 596b911644cc19ecba0dbc9c92849fb59390e29a ] + +Hardware target implements an address space larger than that PCI BAR can +map. In order to be able to access the whole target address space, the BAR +space is split into 4 segments, of which the last 3, called windows, can +be dynamically mapped to the desired area. This is achieved by updating +window register with appropriate window value. Currently each time when +accessing a register that beyond ATH11K_PCI_WINDOW_START, host calculates +the window value and caches it after window update, this way next time +when accessing a register falling in the same window, host knows that the +window is already good hence no additional update needed. + +However this mechanism breaks after global reset is triggered in +ath11k_pci_soc_global_reset(), because with global reset hardware resets +window register hence the window is not properly mapped any more. Current +host does nothing about this, as a result a subsequent register access may +not work as expected if it falls in a window same as before. + +Although there is no obvious issue seen now, better to fix it to avoid +future problem. The fix is done by restoring the window register after +global reset. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251014-ath11k-reset-window-cache-v1-1-b85271b111dd@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index d8655badd96d0..7114eca8810db 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -177,6 +177,19 @@ static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) + ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + } + ++static void ath11k_pci_restore_window(struct ath11k_base *ab) ++{ ++ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); ++ ++ spin_lock_bh(&ab_pci->window_lock); ++ ++ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | ab_pci->register_window, ++ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ++ spin_unlock_bh(&ab_pci->window_lock); ++} ++ + static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + { + u32 val, delay; +@@ -201,6 +214,11 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); + if (val == 0xffffffff) + ath11k_warn(ab, "link down error during global reset\n"); ++ ++ /* Restore window register as its content is cleared during ++ * hardware global reset, such that it aligns with host cache. ++ */ ++ ath11k_pci_restore_window(ab); + } + + static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab) +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch b/queue-6.17/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch new file mode 100644 index 0000000000..4deb45a695 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch @@ -0,0 +1,115 @@ +From fe9c435f7777e8b0e1938db97d3ed7b9b1e9c485 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:08:43 +0800 +Subject: wifi: ath12k: fix error handling in creating hardware group + +From: Baochen Qiang + +[ Upstream commit 088a099690e4c0d291db505013317ab5dd58b4d5 ] + +In ath12k_core_init() when ath12k_core_hw_group_create() fails, +ath12k_core_hw_group_destroy() is called where for each device below +path would get executed + + ath12k_core_soc_destroy() + ath12k_qmi_deinit_service() + qmi_handle_release() + +This results in kernel crash in case one of the device fails at +qmi_handle_init() when creating hardware group: + +ath12k_pci 0000:10:00.0: failed to initialize qmi handle +ath12k_pci 0000:10:00.0: failed to initialize qmi :-517 +ath12k_pci 0000:10:00.0: failed to create soc core: -517 +ath12k_pci 0000:10:00.0: unable to create hw group +BUG: unable to handle page fault for address: ffffffffffffffb7 +RIP: 0010:qmi_handle_release +Call Trace: + + ath12k_qmi_deinit_service + ath12k_core_hw_group_destroy + ath12k_core_init + ath12k_pci_probe + +The detailed reason is, when qmi_handle_init() fails for a device +ab->qmi.handle is not correctly initialized. Then +ath12k_core_hw_group_create() returns failure, since error handing +is done for all device, eventually qmi_handle_release() is called for the +issue device and finally kernel crashes due to the uninitialized +ab->qmi.handle. + +Fix this by moving error handling to ath12k_core_hw_group_create(), this +way the issue device can be skipped. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284.1-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: 6f245ea0ec6c ("wifi: ath12k: introduce device group abstraction") +Link: https://lore.kernel.org/ath12k/fabc97122016d1a66a53ddedd965d134@posteo.net +Reported-by: a-development +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220518 +Tested-by: a-development +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251030-fix-hw-group-create-err-handling-v1-1-0659e4d15fb9@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/core.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c +index 5d494c5cdc0da..a2137b363c2fe 100644 +--- a/drivers/net/wireless/ath/ath12k/core.c ++++ b/drivers/net/wireless/ath/ath12k/core.c +@@ -2106,14 +2106,27 @@ static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag) + ret = ath12k_core_soc_create(ab); + if (ret) { + mutex_unlock(&ab->core_lock); +- ath12k_err(ab, "failed to create soc core: %d\n", ret); +- return ret; ++ ath12k_err(ab, "failed to create soc %d core: %d\n", i, ret); ++ goto destroy; + } + + mutex_unlock(&ab->core_lock); + } + + return 0; ++ ++destroy: ++ for (i--; i >= 0; i--) { ++ ab = ag->ab[i]; ++ if (!ab) ++ continue; ++ ++ mutex_lock(&ab->core_lock); ++ ath12k_core_soc_destroy(ab); ++ mutex_unlock(&ab->core_lock); ++ } ++ ++ return ret; + } + + void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag) +@@ -2188,7 +2201,7 @@ int ath12k_core_init(struct ath12k_base *ab) + if (ret) { + mutex_unlock(&ag->mutex); + ath12k_warn(ab, "unable to create hw group\n"); +- goto err_destroy_hw_group; ++ goto err_unassign_hw_group; + } + } + +@@ -2196,8 +2209,7 @@ int ath12k_core_init(struct ath12k_base *ab) + + return 0; + +-err_destroy_hw_group: +- ath12k_core_hw_group_destroy(ab->ag); ++err_unassign_hw_group: + ath12k_core_hw_group_unassign(ab); + err_unregister_notifier: + ath12k_core_panic_notifier_unregister(ab); +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch b/queue-6.17/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch new file mode 100644 index 0000000000..dc899b74c4 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch @@ -0,0 +1,182 @@ +From fc72b590fb8f2e1f5389bdeeb258c0fa8656dcb6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Sep 2025 14:45:50 +0530 +Subject: wifi: ath12k: Fix MSDU buffer types handling in RX error path + +From: Sarika Sharma + +[ Upstream commit 36f9edbb9d0fc36c865c74f3c1ad8e1261ad3981 ] + +Currently, packets received on the REO exception ring from +unassociated peers are of MSDU buffer type, while the driver expects +link descriptor type packets. These packets are not parsed further due +to a return check on packet type in ath12k_hal_desc_reo_parse_err(), +but the associated skb is not freed. This may lead to kernel +crashes and buffer leaks. + +Hence to fix, update the RX error handler to explicitly drop +MSDU buffer type packets received on the REO exception ring. +This prevents further processing of invalid packets and ensures +stability in the RX error handling path. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Sarika Sharma +Reviewed-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250930091551.3305312-2-sarika.sharma@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_rx.c | 70 ++++++++++++++++++++++-- + drivers/net/wireless/ath/ath12k/hal_rx.c | 10 +--- + 2 files changed, 66 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index 9048818984f19..0be911b4f3166 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3690,6 +3690,48 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, + return 0; + } + ++static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, ++ struct list_head *list, ++ struct hal_reo_dest_ring *desc) ++{ ++ struct ath12k_rx_desc_info *desc_info; ++ struct ath12k_skb_rxcb *rxcb; ++ struct sk_buff *msdu; ++ u64 desc_va; ++ ++ desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | ++ le32_to_cpu(desc->buf_va_lo); ++ desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; ++ if (!desc_info) { ++ u32 cookie; ++ ++ cookie = le32_get_bits(desc->buf_addr_info.info1, ++ BUFFER_ADDR_INFO1_SW_COOKIE); ++ desc_info = ath12k_dp_get_rx_desc(ab, cookie); ++ if (!desc_info) { ++ ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", ++ cookie); ++ return -EINVAL; ++ } ++ } ++ ++ if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { ++ ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", ++ desc_info->magic); ++ return -EINVAL; ++ } ++ ++ msdu = desc_info->skb; ++ desc_info->skb = NULL; ++ list_add_tail(&desc_info->list, list); ++ rxcb = ATH12K_SKB_RXCB(msdu); ++ dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), ++ DMA_FROM_DEVICE); ++ dev_kfree_skb_any(msdu); ++ ++ return 0; ++} ++ + int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) + { +@@ -3734,6 +3776,26 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + drop = false; + ab->device_stats.err_ring_pkts++; + ++ hw_link_id = le32_get_bits(reo_desc->info0, ++ HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); ++ device_id = hw_links[hw_link_id].device_id; ++ partner_ab = ath12k_ag_to_ab(ag, device_id); ++ ++ /* Below case is added to handle data packet from un-associated clients. ++ * As it is expected that AST lookup will fail for ++ * un-associated station's data packets. ++ */ ++ if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == ++ HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { ++ if (!ath12k_dp_h_msdu_buffer_type(partner_ab, ++ &rx_desc_used_list[device_id], ++ reo_desc)) { ++ num_buffs_reaped[device_id]++; ++ tot_n_bufs_reaped++; ++ } ++ goto next_desc; ++ } ++ + ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); + if (ret) { +@@ -3742,11 +3804,6 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + continue; + } + +- hw_link_id = le32_get_bits(reo_desc->info0, +- HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); +- device_id = hw_links[hw_link_id].device_id; +- partner_ab = ath12k_ag_to_ab(ag, device_id); +- + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; +@@ -3795,6 +3852,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + } + } + ++next_desc: + if (tot_n_bufs_reaped >= quota) { + tot_n_bufs_reaped = quota; + goto exit; +diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/hal_rx.c +index 48aa48c48606a..805c31e4243db 100644 +--- a/drivers/net/wireless/ath/ath12k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath12k/hal_rx.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include "debug.h" +@@ -320,7 +320,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, + { + enum hal_reo_dest_ring_push_reason push_reason; + enum hal_reo_dest_ring_error_code err_code; +- u32 cookie, val; ++ u32 cookie; + + push_reason = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_PUSH_REASON); +@@ -335,12 +335,6 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, + return -EINVAL; + } + +- val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); +- if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { +- ath12k_warn(ab, "expected buffer type link_desc"); +- return -EINVAL; +- } +- + ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); + *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); + +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch b/queue-6.17/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch new file mode 100644 index 0000000000..e5eb589ce2 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch @@ -0,0 +1,39 @@ +From 0811356fd3a0bb5fdcb92c7f5e1940ce57ba12ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:34:55 +0530 +Subject: wifi: ath12k: fix potential memory leak in + ath12k_wow_arp_ns_offload() + +From: Abdun Nihaal + +[ Upstream commit be5febd51c478bc8e24ad3480435f2754a403b14 ] + +When the call to ath12k_wmi_arp_ns_offload() fails, the temporary memory +allocation for offload is not freed before returning. Fix that by +freeing offload in the error path. + +Fixes: 1666108c74c4 ("wifi: ath12k: support ARP and NS offload") +Signed-off-by: Abdun Nihaal +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251028170457.134608-1-nihaal@cse.iitm.ac.in +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/wow.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c +index dce9bd0bcaefb..e8481626f1940 100644 +--- a/drivers/net/wireless/ath/ath12k/wow.c ++++ b/drivers/net/wireless/ath/ath12k/wow.c +@@ -758,6 +758,7 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) + if (ret) { + ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n", + arvif->vdev_id, enable, ret); ++ kfree(offload); + return ret; + } + } +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-reusing-m3-memory.patch b/queue-6.17/wifi-ath12k-fix-reusing-m3-memory.patch new file mode 100644 index 0000000000..5652978af1 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-reusing-m3-memory.patch @@ -0,0 +1,107 @@ +From 21b962863a984552f4da13c3107cd8e852177845 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:07:14 +0800 +Subject: wifi: ath12k: fix reusing m3 memory + +From: Baochen Qiang + +[ Upstream commit 00575bb44b2c2aa53d0a768de2b80c9c1af0174d ] + +During firmware recovery or suspend/resume, m3 memory could be reused if +the size of the new m3 binary is equal to or less than that of the +existing memory. There will be issues for the latter case, since +m3_mem->size will be updated with a smaller value and this value is +eventually used in the free path, where the original total size should be +used instead. + +To fix it, add a new member in m3_mem_region structure to track the original +memory size and use it in free path. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 + +Fixes: 05090ae82f44 ("wifi: ath12k: check M3 buffer size as well whey trying to reuse it") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251029-ath12k-fix-m3-reuse-v1-1-69225bacfc5d@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++---- + drivers/net/wireless/ath/ath12k/qmi.h | 5 ++++- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c +index 7c611a1fd6d07..9c03a890e6cf2 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.c ++++ b/drivers/net/wireless/ath/ath12k/qmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3114,9 +3114,10 @@ static void ath12k_qmi_m3_free(struct ath12k_base *ab) + if (!m3_mem->vaddr) + return; + +- dma_free_coherent(ab->dev, m3_mem->size, ++ dma_free_coherent(ab->dev, m3_mem->total_size, + m3_mem->vaddr, m3_mem->paddr); + m3_mem->vaddr = NULL; ++ m3_mem->total_size = 0; + m3_mem->size = 0; + } + +@@ -3152,7 +3153,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + + /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */ + if (m3_mem->vaddr) { +- if (m3_mem->size >= m3_len) ++ if (m3_mem->total_size >= m3_len) + goto skip_m3_alloc; + + /* Old buffer is too small, free and reallocate */ +@@ -3164,11 +3165,13 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + GFP_KERNEL); + if (!m3_mem->vaddr) { + ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n", +- fw->size); ++ m3_len); + ret = -ENOMEM; + goto out; + } + ++ m3_mem->total_size = m3_len; ++ + 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 abdaade3b542a..92962cd009ad5 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.h ++++ b/drivers/net/wireless/ath/ath12k/qmi.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #ifndef ATH12K_QMI_H +@@ -120,6 +120,9 @@ struct target_info { + }; + + struct m3_mem_region { ++ /* total memory allocated */ ++ u32 total_size; ++ /* actual memory being used */ + u32 size; + dma_addr_t paddr; + void *vaddr; +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch b/queue-6.17/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch new file mode 100644 index 0000000000..d4048dc0d0 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch @@ -0,0 +1,102 @@ +From cd946ff683e08a4fea1ad4ea7cdb06b5512eb96e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 08:37:46 +0530 +Subject: wifi: ath12k: Fix timeout error during beacon stats retrieval + +From: Manish Dharanenthiran + +[ Upstream commit 2977567b244f056d86658160659f06cd6c78ba3d ] + +Currently, for beacon_stats, ath12k_mac_get_fw_stats() is called +for each started BSS on the specified hardware. +ath12k_mac_get_fw_stats() will wait for the fw_stats_done completion +after fetching the requested data from firmware. For the beacon_stats, +fw_stats_done completion will be set only when stats are received for +all BSSes. However, for other stats like vdev_stats or pdev_stats, there +is one request to the firmware for all enabled BSSes. Since beacon_stats +is fetched individually for all BSSes enabled in that pdev, waiting for +the completion event results in a timeout error when multiple BSSes are +enabled. + +Avoid this by completing the fw_stats_done immediately after +updating the requested BSS's beacon stats in the list. Subsequently, +this list will be used to display the beacon stats for all enabled +BSSes in the requested pdev. + +Additionally, remove 'num_bcn_recvd' from the ath12k_fw_stats struct +as it is no longer needed. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 9fe4669ae919 ("wifi: ath12k: Request beacon stats from firmware") +Signed-off-by: Manish Dharanenthiran +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251031-beacon_stats-v1-2-f52fce7b03ac@qti.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/core.c | 2 -- + drivers/net/wireless/ath/ath12k/core.h | 1 - + drivers/net/wireless/ath/ath12k/wmi.c | 10 +--------- + 3 files changed, 1 insertion(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c +index a2137b363c2fe..cc352eef19399 100644 +--- a/drivers/net/wireless/ath/ath12k/core.c ++++ b/drivers/net/wireless/ath/ath12k/core.c +@@ -1,7 +1,6 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -1250,7 +1249,6 @@ void ath12k_fw_stats_reset(struct ath12k *ar) + spin_lock_bh(&ar->data_lock); + ath12k_fw_stats_free(&ar->fw_stats); + ar->fw_stats.num_vdev_recvd = 0; +- ar->fw_stats.num_bcn_recvd = 0; + spin_unlock_bh(&ar->data_lock); + } + +diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h +index 519f826f56c8e..65b75cae1fb99 100644 +--- a/drivers/net/wireless/ath/ath12k/core.h ++++ b/drivers/net/wireless/ath/ath12k/core.h +@@ -640,7 +640,6 @@ struct ath12k_fw_stats { + struct list_head vdevs; + struct list_head bcn; + u32 num_vdev_recvd; +- u32 num_bcn_recvd; + }; + + struct ath12k_dbg_htt_stats { +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index c69be688e189c..82d0773b0380d 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -8298,18 +8298,10 @@ static void ath12k_wmi_fw_stats_process(struct ath12k *ar, + ath12k_warn(ab, "empty beacon stats"); + return; + } +- /* Mark end until we reached the count of all started VDEVs +- * within the PDEV +- */ +- if (ar->num_started_vdevs) +- is_end = ((++ar->fw_stats.num_bcn_recvd) == +- ar->num_started_vdevs); + + list_splice_tail_init(&stats->bcn, + &ar->fw_stats.bcn); +- +- if (is_end) +- complete(&ar->fw_stats_done); ++ complete(&ar->fw_stats_done); + } + } + +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch b/queue-6.17/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch new file mode 100644 index 0000000000..17b378be66 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch @@ -0,0 +1,58 @@ +From 855de2c737ea46ee82f1980534afb554dc00fda5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:16:56 -0700 +Subject: wifi: ath12k: fix TX and RX MCS rate configurations in HE mode + +From: Pradeep Kumar Chitrapu + +[ Upstream commit 9c5f229b1312a31aff762b2111f6751e4e3722fe ] + +Currently, the TX and RX MCS rate configurations per peer are +reversed when sent to the firmware. As a result, RX MCS rates +are configured for TX, and vice versa. This commit rectifies +the configuration to match what the firmware expects. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Pradeep Kumar Chitrapu +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251009211656.2386085-3-quic_pradeepc@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 828abccda125a..98b684b27566a 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -2638,9 +2638,10 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, + switch (link_sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + +- v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); ++ v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2650,10 +2651,10 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-fix-vht-mcs-assignment.patch b/queue-6.17/wifi-ath12k-fix-vht-mcs-assignment.patch new file mode 100644 index 0000000000..2fab26be78 --- /dev/null +++ b/queue-6.17/wifi-ath12k-fix-vht-mcs-assignment.patch @@ -0,0 +1,114 @@ +From 0c5e47cf86fda59b97fddd06d1f056ee63a52adc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:16:55 -0700 +Subject: wifi: ath12k: fix VHT MCS assignment + +From: Baochen Qiang + +[ Upstream commit 8c21b32c2cc82224c7fc1a9f67318f3b1199744b ] + +While associating, firmware needs the peer's receive capability +to calculate its own VHT transmit MCS. Currently, the host +sends this information via mcs->rx_mcs_set field, but firmware +actually reads it from mcs->tx_mcs_set field. This mismatch is +incorrect. + +This issue has not caused failures so far because most peers +advertise identical TX and RX capabilities. Fix this by +assigning the value to tx_mcs_set as expected. + +Additionally, the rate control mask is intended to limit our +transmit MCS, so it should also apply to the peer's receive +capability. Update the logic accordingly. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Baochen Qiang +Signed-off-by: Pradeep Kumar Chitrapu +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251009211656.2386085-2-quic_pradeepc@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 7 +++---- + drivers/net/wireless/ath/ath12k/wmi.c | 13 ++++++++----- + drivers/net/wireless/ath/ath12k/wmi.h | 2 ++ + 3 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index fd584633392c1..828abccda125a 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -2263,7 +2263,6 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, + struct cfg80211_chan_def def; + enum nl80211_band band; + u16 *vht_mcs_mask; +- u16 tx_mcs_map; + u8 ampdu_factor; + u8 max_nss, vht_mcs; + int i, vht_nss, nss_idx; +@@ -2354,10 +2353,10 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, + arg->peer_nss = min(link_sta->rx_nss, max_nss); + arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); + arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); +- arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); ++ arg->rx_mcs_set = ath12k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); + +- tx_mcs_map = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); +- arg->tx_mcs_set = ath12k_peer_assoc_h_vht_limit(tx_mcs_map, vht_mcs_mask); ++ arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); ++ arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); + + /* In QCN9274 platform, VHT MCS rate 10 and 11 is enabled by default. + * VHT MCS rate 10 and 11 is not supported in 11ac standard. +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index 29dadedefdd27..c69be688e189c 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -2362,10 +2362,13 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar, + cmd->peer_bw_rxnss_override |= cpu_to_le32(arg->peer_bw_rxnss_override); + + if (arg->vht_capable) { +- mcs->rx_max_rate = cpu_to_le32(arg->rx_max_rate); +- mcs->rx_mcs_set = cpu_to_le32(arg->rx_mcs_set); +- mcs->tx_max_rate = cpu_to_le32(arg->tx_max_rate); +- mcs->tx_mcs_set = cpu_to_le32(arg->tx_mcs_set); ++ /* Firmware interprets mcs->tx_mcs_set field as peer's ++ * RX capability ++ */ ++ mcs->rx_max_rate = cpu_to_le32(arg->tx_max_rate); ++ mcs->rx_mcs_set = cpu_to_le32(arg->tx_mcs_set); ++ mcs->tx_max_rate = cpu_to_le32(arg->rx_max_rate); ++ mcs->tx_mcs_set = cpu_to_le32(arg->rx_mcs_set); + } + + /* HE Rates */ +diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h +index f3b0a6f57ec2b..62d570a846da2 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.h ++++ b/drivers/net/wireless/ath/ath12k/wmi.h +@@ -4218,8 +4218,10 @@ struct wmi_unit_test_cmd { + struct ath12k_wmi_vht_rate_set_params { + __le32 tlv_header; + __le32 rx_max_rate; ++ /* MCS at which the peer can transmit */ + __le32 rx_mcs_set; + __le32 tx_max_rate; ++ /* MCS at which the peer can receive */ + __le32 tx_mcs_set; + __le32 tx_max_mcs_nss; + } __packed; +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-restore-register-window-after-global-res.patch b/queue-6.17/wifi-ath12k-restore-register-window-after-global-res.patch new file mode 100644 index 0000000000..d1bbbf930a --- /dev/null +++ b/queue-6.17/wifi-ath12k-restore-register-window-after-global-res.patch @@ -0,0 +1,91 @@ +From 16465557460a9a9f10ca11a1cdea497bf5eca8ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 10:36:36 +0800 +Subject: wifi: ath12k: restore register window after global reset + +From: Baochen Qiang + +[ Upstream commit a41281f6518e485220d180a6031d302a736fc463 ] + +Hardware target implements an address space larger than that PCI BAR can +map. In order to be able to access the whole target address space, the +BAR space is split into 4 segments, of which the last 3, called windows, +can be dynamically mapped to the desired area. This is achieved by +updating WINDOW_REG_ADDRESS register with appropriate window value. +Currently each time when accessing a register that beyond WINDOW_START, +host calculates the window value and caches it after window update, +this way next time when accessing a register falling in the same window, +host knows that the window is already good hence no additional update +needed. + +However this mechanism breaks after global reset is triggered in +ath12k_pci_soc_global_reset(), because with global reset hardware resets +WINDOW_REG_ADDRESS register hence the window is not properly mapped any +more. Current host does nothing about this, as a result a subsequent +register access may not work as expected if it falls in a window same as +before. + +Although there is no obvious issue seen now, better to fix it to avoid +future problem. The fix is done by restoring the window register after +global reset. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284.1-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath12k-reset-window-cache-v1-1-29e0e751deed@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c +index c729d5526c753..60b8f7361b7f6 100644 +--- a/drivers/net/wireless/ath/ath12k/pci.c ++++ b/drivers/net/wireless/ath/ath12k/pci.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -218,6 +218,19 @@ static inline bool ath12k_pci_is_offset_within_mhi_region(u32 offset) + return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END); + } + ++static void ath12k_pci_restore_window(struct ath12k_base *ab) ++{ ++ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); ++ ++ spin_lock_bh(&ab_pci->window_lock); ++ ++ iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window, ++ ab->mem + WINDOW_REG_ADDRESS); ++ ioread32(ab->mem + WINDOW_REG_ADDRESS); ++ ++ spin_unlock_bh(&ab_pci->window_lock); ++} ++ + static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) + { + u32 val, delay; +@@ -242,6 +255,11 @@ static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) + val = ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET); + if (val == 0xffffffff) + ath12k_warn(ab, "link down error during global reset\n"); ++ ++ /* Restore window register as its content is cleared during ++ * hardware global reset, such that it aligns with host cache. ++ */ ++ ath12k_pci_restore_window(ab); + } + + static void ath12k_pci_clear_dbg_registers(struct ath12k_base *ab) +-- +2.51.0 + diff --git a/queue-6.17/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch b/queue-6.17/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch new file mode 100644 index 0000000000..09d2180d9b --- /dev/null +++ b/queue-6.17/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch @@ -0,0 +1,57 @@ +From ce5f3db1c00063bbd5a4cd905e38d75e812362e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Oct 2025 23:52:54 +0530 +Subject: wifi: ath12k: unassign arvif on scan vdev create failure + +From: Rameshkumar Sundaram + +[ Upstream commit e70515039d44be61b6a73aafb401d141b0034d12 ] + +During scan and remain-on-channel requests, a scan link vif (arvif) is +assigned and a temporary vdev is created. If vdev creation fails, the +assigned arvif is left attached until the virtual interface is removed, +leaving a stale link in ahvif. + +Fix this by freeing the stale arvif and resetting the corresponding link in +ahvif by calling ath12k_mac_unassign_link_vif() when vdev creation fails. + +While at it, propagate the actual error code from ath12k_mac_vdev_create() +instead of returning -EINVAL in ath12k_mac_initiate_hw_scan(). + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO") +Signed-off-by: Rameshkumar Sundaram +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251026182254.1399650-3-rameshkumar.sundaram@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 98b684b27566a..6bdcf5ecb39e5 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -5073,7 +5073,8 @@ static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, + ret = ath12k_mac_vdev_create(ar, arvif); + if (ret) { + ath12k_warn(ar->ab, "unable to create scan vdev %d\n", ret); +- return -EINVAL; ++ ath12k_mac_unassign_link_vif(arvif); ++ return ret; + } + } + +@@ -12846,6 +12847,7 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + if (ret) { + ath12k_warn(ar->ab, "unable to create scan vdev for roc: %d\n", + ret); ++ ath12k_mac_unassign_link_vif(arvif); + return ret; + } + } +-- +2.51.0 + diff --git a/queue-6.17/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-6.17/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..1c418695f7 --- /dev/null +++ b/queue-6.17/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From b1589c1530acbee1023be6c9b99824014515f08a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 3b4ded2ac801c..37232ee220375 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-6.17/wifi-ieee80211-correct-fils-status-codes.patch b/queue-6.17/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..b1d2b670e3 --- /dev/null +++ b/queue-6.17/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From 73b4e402dcd84900d1e10c73a57952a62d97543c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index e5a2096e022ef..e3562770ffff3 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3572,8 +3572,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133, +-- +2.51.0 + diff --git a/queue-6.17/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch b/queue-6.17/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch new file mode 100644 index 0000000000..b541d79366 --- /dev/null +++ b/queue-6.17/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch @@ -0,0 +1,41 @@ +From c02d6dc6f4ddcecb4ceb93e392064489c02ea66d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 12:11:28 +0800 +Subject: wifi: iwlwifi: mld: add null check for kzalloc() in + iwl_mld_send_proto_offload() + +From: Li Qiang + +[ Upstream commit 3df28496673bd8009f1cd3a85a63650c96e369f4 ] + +Add a missing NULL pointer check after kzalloc() in +iwl_mld_send_proto_offload(). Without this check, a failed +allocation could lead to a NULL dereference. + +Fixes: d1e879ec600f9 ("wifi: iwlwifi: add iwlmld sub-driver") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251017041128.1379715-1-liqiang01@kylinos.cn +Signed-off-by: Miri Korenblit +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mld/d3.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c +index ed0a0f76f1c51..de669e9ae55a5 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c +@@ -1632,6 +1632,10 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld, + u32 enabled = 0; + + cmd = kzalloc(hcmd.len[0], GFP_KERNEL); ++ if (!cmd) { ++ IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n"); ++ return -ENOMEM; ++ } + + #if IS_ENABLED(CONFIG_IPV6) + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); +-- +2.51.0 + diff --git a/queue-6.17/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch b/queue-6.17/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch new file mode 100644 index 0000000000..97d273b00a --- /dev/null +++ b/queue-6.17/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch @@ -0,0 +1,196 @@ +From 90065b34a69c77dc3fd0d1c2d5bff5c44d525af1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:05:07 +0800 +Subject: wifi: mac80211: fix CMAC functions not handling errors + +From: Chien Wong + +[ Upstream commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb ] + +The called hash functions could fail thus we should check return values. + +Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver") +Signed-off-by: Chien Wong +Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ + net/mac80211/aes_cmac.h | 8 +++--- + net/mac80211/wpa.c | 20 +++++++------ + 3 files changed, 61 insertions(+), 30 deletions(-) + +diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c +index 48c04f89de20a..65989c7dfc680 100644 +--- a/net/mac80211/aes_cmac.c ++++ b/net/mac80211/aes_cmac.c +@@ -22,50 +22,77 @@ + + static const u8 zero[CMAC_TLEN_256]; + +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + u8 out[AES_BLOCK_SIZE]; + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN); ++ err = crypto_shash_update(desc, data, ++ data_len - CMAC_TLEN); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN, out); +- ++ err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); ++ if (err) ++ return err; + memcpy(mic, out, CMAC_TLEN); ++ ++ return 0; + } + +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, +- data_len - 8 - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN_256); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); ++ return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); + } + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h +index 76817446fb838..f74150542142a 100644 +--- a/net/mac80211/aes_cmac.h ++++ b/net/mac80211/aes_cmac.h +@@ -11,10 +11,10 @@ + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len); +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); + void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); + + #endif /* AES_CMAC_H */ +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 40d5d9e484791..bb0fa505cdcae 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -869,8 +869,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) + /* + * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) + */ +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -916,8 +917,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) + + /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) + */ +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -956,8 +958,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +@@ -1006,8 +1009,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7921-add-mbssid-support.patch b/queue-6.17/wifi-mt76-mt7921-add-mbssid-support.patch new file mode 100644 index 0000000000..986ab8dd0a --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7921-add-mbssid-support.patch @@ -0,0 +1,80 @@ +From 1fd497a9955173f13c5733f71a35b181f54ed133 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Aug 2025 19:16:42 +0800 +Subject: wifi: mt76: mt7921: add MBSSID support + +From: Ming Yen Hsieh + +[ Upstream commit 7ae99dd459ba1ea83a9b3d8de254f374182e602c ] + +Enable MBSSID support for MT7921 by setting the +appropriate capability to the firmware. + +Signed-off-by: Ming Yen Hsieh +Link: https://patch.msgid.link/20250812111642.3620845-1-mingyen.hsieh@mediatek.com +Signed-off-by: Felix Fietkau +Stable-dep-of: cdb2941a516c ("Revert "wifi: mt76: mt792x: improve monitor interface handling"") +Signed-off-by: Sasha Levin +--- + .../wireless/mediatek/mt76/mt76_connac_mcu.c | 25 +++++++++++++++++++ + .../net/wireless/mediatek/mt76/mt792x_core.c | 5 ++-- + 2 files changed, 27 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +index 16db0f2082d1e..fc3e6728fcfbf 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +@@ -1662,6 +1662,31 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy, + return err; + } + ++ if (enable && vif->bss_conf.bssid_indicator) { ++ struct { ++ struct { ++ u8 bss_idx; ++ u8 pad[3]; ++ } __packed hdr; ++ struct bss_info_uni_mbssid mbssid; ++ } mbssid_req = { ++ .hdr = { ++ .bss_idx = mvif->idx, ++ }, ++ .mbssid = { ++ .tag = cpu_to_le16(UNI_BSS_INFO_11V_MBSSID), ++ .len = cpu_to_le16(sizeof(struct bss_info_uni_mbssid)), ++ .max_indicator = vif->bss_conf.bssid_indicator, ++ .mbss_idx = vif->bss_conf.bssid_index, ++ }, ++ }; ++ ++ err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), ++ &mbssid_req, sizeof(mbssid_req), true); ++ if (err < 0) ++ return err; ++ } ++ + return mt76_connac_mcu_uni_set_chctx(phy, mvif, ctx); + } + EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss); +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +index 44378f7394e8d..c0e56541a9547 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +@@ -689,12 +689,11 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); + ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR); ++ ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); ++ ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); + + if (is_mt7921(&dev->mt76)) { + ieee80211_hw_set(hw, CHANCTX_STA_CSA); +- } else { +- ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); +- ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); + } + + if (dev->pm.enable) +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7925-add-mbssid-support.patch b/queue-6.17/wifi-mt76-mt7925-add-mbssid-support.patch new file mode 100644 index 0000000000..ec48a14a6b --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7925-add-mbssid-support.patch @@ -0,0 +1,99 @@ +From ae48fcf891e73fb6004058253128f59c639c9b6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 29 Jul 2025 16:49:32 +0800 +Subject: wifi: mt76: mt7925: add MBSSID support + +From: Ming Yen Hsieh + +[ Upstream commit 74e756b9e28af3ee94a7ea480bb39694be5fbd96 ] + +Enable MBSSID support for MT7925 by setting the +appropriate capability to the firmware. + +Signed-off-by: Ming Yen Hsieh +Link: https://patch.msgid.link/20250729084932.264155-1-mingyen.hsieh@mediatek.com +Signed-off-by: Felix Fietkau +Stable-dep-of: cdb2941a516c ("Revert "wifi: mt76: mt792x: improve monitor interface handling"") +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7925/main.c | 1 + + .../net/wireless/mediatek/mt76/mt7925/mcu.c | 23 ++++++++++++++++++- + .../net/wireless/mediatek/mt76/mt792x_core.c | 7 +++++- + 3 files changed, 29 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c +index b0e053b152273..c7903972b1d59 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c +@@ -240,6 +240,7 @@ int mt7925_init_mlo_caps(struct mt792x_phy *phy) + { + struct wiphy *wiphy = phy->mt76->hw->wiphy; + static const u8 ext_capa_sta[] = { ++ [2] = WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT, + [7] = WLAN_EXT_CAPA8_OPMODE_NOTIF, + }; + static struct wiphy_iftype_ext_capab ext_capab[] = { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +index cd457be26523e..10d68d241ba1f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +@@ -2621,6 +2621,25 @@ mt7925_mcu_bss_qos_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf + qos->qos = link_conf->qos; + } + ++static void ++mt7925_mcu_bss_mbssid_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf, ++ bool enable) ++{ ++ struct bss_info_uni_mbssid *mbssid; ++ struct tlv *tlv; ++ ++ if (!enable && !link_conf->bssid_indicator) ++ return; ++ ++ tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_11V_MBSSID, ++ sizeof(*mbssid)); ++ ++ mbssid = (struct bss_info_uni_mbssid *)tlv; ++ mbssid->max_indicator = link_conf->bssid_indicator; ++ mbssid->mbss_idx = link_conf->bssid_index; ++ mbssid->tx_bss_omac_idx = 0; ++} ++ + static void + mt7925_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf, + struct mt792x_phy *phy) +@@ -2787,8 +2806,10 @@ int mt7925_mcu_add_bss_info(struct mt792x_phy *phy, + mt7925_mcu_bss_color_tlv(skb, link_conf, enable); + } + +- if (enable) ++ if (enable) { + mt7925_mcu_bss_rlm_tlv(skb, phy->mt76, link_conf, ctx); ++ mt7925_mcu_bss_mbssid_tlv(skb, link_conf, enable); ++ } + + return mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_UNI_CMD(BSS_INFO_UPDATE), true); +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +index e3a703398b30c..44378f7394e8d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +@@ -689,8 +689,13 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); + ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR); +- if (is_mt7921(&dev->mt76)) ++ ++ if (is_mt7921(&dev->mt76)) { + ieee80211_hw_set(hw, CHANCTX_STA_CSA); ++ } else { ++ ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); ++ ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); ++ } + + if (dev->pm.enable) + ieee80211_hw_set(hw, CONNECTION_MONITOR); +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch b/queue-6.17/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch new file mode 100644 index 0000000000..ea39ca94a1 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch @@ -0,0 +1,46 @@ +From d44a9bcbbbdfcc635b3c2502ff834ab131c51dc8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 10:30:26 +0100 +Subject: wifi: mt76: mt7996: Add missing locking in mt7996_mac_sta_rc_work() + +From: Lorenzo Bianconi + +[ Upstream commit 7545551631fa63101f97974f49ac0b564814f703 ] + +Grab the mt76 mutex running mt7996_mac_sta_rc_work() since it is +required by mt7996_mcu_add_rate_ctrl routine. + +Fixes: 28d519d0d493a ("wifi: mt76: Move RCU section in mt7996_mcu_add_rate_ctrl_fixed()") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251118-mt7996-rc-work-missing-mtx-v1-1-0739c493a6cb@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index b0092794f37c9..4662111ad064d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -2338,6 +2338,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) + LIST_HEAD(list); + u32 changed; + ++ mutex_lock(&dev->mt76.mutex); ++ + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->sta_rc_list, &list); + +@@ -2370,6 +2372,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) + } + + spin_unlock_bh(&dev->mt76.sta_poll_lock); ++ ++ mutex_unlock(&dev->mt76.mutex); + } + + void mt7996_mac_work(struct work_struct *work) +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch b/queue-6.17/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch new file mode 100644 index 0000000000..1790e1b3f9 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch @@ -0,0 +1,41 @@ +From 631c127692ad89495425c29ced5d57bb21159ca1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:54 +0800 +Subject: wifi: mt76: mt7996: fix implicit beamforming support for mt7992 + +From: Howard Hsu + +[ Upstream commit 5d86765828b47444908a8689f2625872e8dac48f ] + +Fix the ibf_timeout field for mt7996, mt7992 and mt7990 chipsets. For +the mt7992, this value shall be set as 0xff, while the others shall be +set as 0x18. + +Fixes: ad4c9a8a9803 ("wifi: mt76: mt7996: add implicit beamforming support for mt7992") +Signed-off-by: Howard Hsu +Signed-off-by: Shayne Chen +Link: https://patch.msgid.link/20251106064203.1000505-3-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 07b962e235850..f337e3267c6f0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -1754,8 +1754,8 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, + bf->ibf_nrow = tx_ant; + + if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he) +- bf->ibf_timeout = is_mt7996(&dev->mt76) ? MT7996_IBF_TIMEOUT : +- MT7992_IBF_TIMEOUT; ++ bf->ibf_timeout = is_mt7992(&dev->mt76) ? MT7992_IBF_TIMEOUT : ++ MT7996_IBF_TIMEOUT; + else if (!ebf && link_sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) + bf->ibf_timeout = MT7996_IBF_TIMEOUT_LEGACY; + else +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch b/queue-6.17/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch new file mode 100644 index 0000000000..69609cfb2e --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch @@ -0,0 +1,39 @@ +From 1adf4922aa98b80c29aafe9f88cbd93f7b40ffec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:52 +0800 +Subject: wifi: mt76: mt7996: fix max nss value when getting rx chainmask + +From: StanleyYP Wang + +[ Upstream commit 361b59b6be7c33c43b619d5cada394efc0f3b398 ] + +Since wiphy->available_antennas_tx now accumulates the chainmask of all +the radios of a wiphy, use phy->orig_antenna_mask to get the original +max nss for comparison. + +Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy") +Signed-off-by: StanleyYP Wang +Signed-off-by: Shayne Chen +Link: https://patch.msgid.link/20251106064203.1000505-1-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +index 498a2eefd7a8a..5a415424291f8 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +@@ -720,7 +720,7 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset, + + static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy) + { +- int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx); ++ int max_nss = hweight16(phy->orig_antenna_mask); + int cur_nss = hweight8(phy->mt76->antenna_mask); + u16 tx_chainmask = phy->mt76->chainmask; + +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch b/queue-6.17/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch new file mode 100644 index 0000000000..cc04ec5397 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch @@ -0,0 +1,123 @@ +From 8c6643c8289003bb52fce62b5ef58822654f43b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:00 +0800 +Subject: wifi: mt76: mt7996: fix MLD group index assignment + +From: Shayne Chen + +[ Upstream commit 4fb3b4e7d1ca5453c6167816230370afc15f26bf ] + +Fix extender mode and MBSS issues caused by incorrect assignment of the +MLD group and remap indices. + +Fixes: ed01c310eca9 ("wifi: mt76: mt7996: Fix mt7996_mcu_bss_mld_tlv routine") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-9-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/main.c | 58 +++++++++++++------ + 1 file changed, 40 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index b8bd2bda5172f..14e90ecf925e1 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -90,9 +90,11 @@ static void mt7996_stop(struct ieee80211_hw *hw, bool suspend) + { + } + +-static inline int get_free_idx(u32 mask, u8 start, u8 end) ++static inline int get_free_idx(u64 mask, u8 start, u8 end) + { +- return ffs(~mask & GENMASK(end, start)); ++ if (~mask & GENMASK_ULL(end, start)) ++ return __ffs64(~mask & GENMASK_ULL(end, start)) + 1; ++ return 0; + } + + static int get_omac_idx(enum nl80211_iftype type, u64 mask) +@@ -311,12 +313,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + if (idx < 0) + return -ENOSPC; + +- if (!dev->mld_idx_mask) { /* first link in the group */ +- mvif->mld_group_idx = get_own_mld_idx(dev->mld_idx_mask, true); +- mvif->mld_remap_idx = get_free_idx(dev->mld_remap_idx_mask, +- 0, 15); +- } +- + mld_idx = get_own_mld_idx(dev->mld_idx_mask, false); + if (mld_idx < 0) + return -ENOSPC; +@@ -334,10 +330,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + return ret; + + dev->mt76.vif_mask |= BIT_ULL(mlink->idx); +- if (!dev->mld_idx_mask) { +- dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); +- dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); +- } + dev->mld_idx_mask |= BIT_ULL(link->mld_idx); + phy->omac_mask |= BIT_ULL(mlink->omac_idx); + +@@ -421,11 +413,6 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, + dev->mt76.vif_mask &= ~BIT_ULL(mlink->idx); + dev->mld_idx_mask &= ~BIT_ULL(link->mld_idx); + phy->omac_mask &= ~BIT_ULL(mlink->omac_idx); +- if (!(dev->mld_idx_mask & ~BIT_ULL(mvif->mld_group_idx))) { +- /* last link */ +- dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); +- dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); +- } + + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta_link->wcid.poll_list)) +@@ -2181,7 +2168,42 @@ mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) + { +- return 0; ++ struct mt7996_dev *dev = mt7996_hw_dev(hw); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ int ret = 0; ++ ++ mutex_lock(&dev->mt76.mutex); ++ ++ if (!old_links) { ++ int idx; ++ ++ idx = get_own_mld_idx(dev->mld_idx_mask, true); ++ if (idx < 0) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ mvif->mld_group_idx = idx; ++ dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); ++ ++ idx = get_free_idx(dev->mld_remap_idx_mask, 0, 15) - 1; ++ if (idx < 0) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ mvif->mld_remap_idx = idx; ++ dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); ++ } ++ ++ if (new_links) ++ goto out; ++ ++ dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); ++ dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); ++ ++out: ++ mutex_unlock(&dev->mt76.mutex); ++ ++ return ret; + } + + const struct ieee80211_ops mt7996_ops = { +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch b/queue-6.17/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch new file mode 100644 index 0000000000..8f3e2535f2 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch @@ -0,0 +1,102 @@ +From be334184aa6f6931fe5f9421cc9f82e219baac6e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 13:17:23 +0200 +Subject: wifi: mt76: mt7996: fix null pointer deref in mt7996_conf_tx() + +From: Felix Fietkau + +[ Upstream commit 79277f8ad15ec5f255ed0e1427c7a8a3e94e7f52 ] + +If a link does not have an assigned channel yet, mt7996_vif_link returns +NULL. We still need to store the updated queue settings in that case, and +apply them later. +Move the location of the queue params to within struct mt7996_vif_link. + +Fixes: c0df2f0caa8d ("wifi: mt76: mt7996: prepare mt7996_mcu_set_tx for MLO support") +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250929111723.52486-1-nbd@nbd.name +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 +++--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 5 ++++- + drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 7 ++++++- + 3 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 4693d376e64ee..016b7e02d969d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -650,8 +650,8 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params) + { +- struct mt7996_dev *dev = mt7996_hw_dev(hw); +- struct mt7996_vif_link *mlink = mt7996_vif_link(dev, vif, link_id); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; + static const u8 mq_to_aci[] = { + [IEEE80211_AC_VO] = 3, + [IEEE80211_AC_VI] = 2, +@@ -660,7 +660,7 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + }; + + /* firmware uses access class index */ +- mlink->queue_params[mq_to_aci[queue]] = *params; ++ link_info->queue_params[mq_to_aci[queue]] = *params; + /* no need to update right away, we'll get BSS_CHANGED_QOS */ + + return 0; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 0d688ec5a8163..07b962e235850 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -3438,6 +3438,9 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + #define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \ + WMM_CW_MAX_SET | WMM_TXOP_SET) + struct mt7996_vif_link *link = mt7996_vif_conf_link(dev, vif, link_conf); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ unsigned int link_id = link_conf->link_id; ++ struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; + struct { + u8 bss_idx; + u8 __rsv[3]; +@@ -3455,7 +3458,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + skb_put_data(skb, &hdr, sizeof(hdr)); + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +- struct ieee80211_tx_queue_params *q = &link->queue_params[ac]; ++ struct ieee80211_tx_queue_params *q = &link_info->queue_params[ac]; + struct edca *e; + struct tlv *tlv; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +index 048d9a9898c6e..498a2eefd7a8a 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +@@ -246,16 +246,21 @@ struct mt7996_vif_link { + struct mt7996_sta_link msta_link; + struct mt7996_phy *phy; + +- struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct cfg80211_bitrate_mask bitrate_mask; + + u8 mld_idx; + }; + ++struct mt7996_vif_link_info { ++ struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; ++}; ++ + struct mt7996_vif { + struct mt7996_vif_link deflink; /* must be first */ + struct mt76_vif_data mt76; + ++ struct mt7996_vif_link_info link_info[IEEE80211_MLD_MAX_NUM_LINKS]; ++ + u8 mld_group_idx; + u8 mld_remap_idx; + }; +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch b/queue-6.17/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch new file mode 100644 index 0000000000..555e7890ad --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch @@ -0,0 +1,84 @@ +From 491d59fa3ad73fe81ff0fd0e09a72fe423dd267a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:56 +0800 +Subject: wifi: mt76: mt7996: fix several fields in mt7996_mcu_bss_basic_tlv() + +From: Shayne Chen + +[ Upstream commit bb705a606734e1ce0ff17a4f368a896757ba686d ] + +Fix several fields in mt7996_mcu_bss_basic_tlv() that were not obtained +from the correct link. Without this patch, the MLD station interface +does not function properly. + +Fixes: 34a41bfbcb71 ("wifi: mt76: mt7996: prepare mt7996_mcu_add_dev/bss_info for MLO support") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-5-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/mcu.c | 21 ++++++++++--------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index f337e3267c6f0..ff9b70292bfd0 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -1010,7 +1010,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + struct mt76_connac_bss_basic_tlv *bss; + u32 type = CONNECTION_INFRA_AP; + u16 sta_wlan_idx = wlan_idx; +- struct ieee80211_sta *sta; + struct tlv *tlv; + int idx; + +@@ -1021,14 +1020,18 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + break; + case NL80211_IFTYPE_STATION: + if (enable) { ++ struct ieee80211_sta *sta; ++ + rcu_read_lock(); +- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); +- /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ ++ sta = ieee80211_find_sta(vif, link_conf->bssid); + if (sta) { +- struct mt76_wcid *wcid; ++ struct mt7996_sta *msta = (void *)sta->drv_priv; ++ struct mt7996_sta_link *msta_link; ++ int link_id = link_conf->link_id; + +- wcid = (struct mt76_wcid *)sta->drv_priv; +- sta_wlan_idx = wcid->idx; ++ msta_link = rcu_dereference(msta->link[link_id]); ++ if (msta_link) ++ sta_wlan_idx = msta_link->wcid.idx; + } + rcu_read_unlock(); + } +@@ -1045,8 +1048,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss)); + + bss = (struct mt76_connac_bss_basic_tlv *)tlv; +- bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); +- bss->dtim_period = link_conf->dtim_period; + bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); + bss->sta_idx = cpu_to_le16(sta_wlan_idx); + bss->conn_type = cpu_to_le32(type); +@@ -1066,10 +1067,10 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + + memcpy(bss->bssid, link_conf->bssid, ETH_ALEN); + bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); +- bss->dtim_period = vif->bss_conf.dtim_period; ++ bss->dtim_period = link_conf->dtim_period; + bss->phymode = mt76_connac_get_phy_mode(phy, vif, + chandef->chan->band, NULL); +- bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, &vif->bss_conf, ++ bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, link_conf, + chandef->chan->band); + + return 0; +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch b/queue-6.17/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch new file mode 100644 index 0000000000..ce7106de28 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch @@ -0,0 +1,48 @@ +From a70a91b74415112f7e6327c7e45a5b7c7a8f327b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:57 +0800 +Subject: wifi: mt76: mt7996: fix teardown command for an MLD peer + +From: Shayne Chen + +[ Upstream commit e077071e7ac48d5453072f615d51629891c5b90d ] + +For an MLD peer, we only need to call the teardown command when removing +the last link, and there's no need to call mt7996_mcu_add_sta() for the +earlier links. + +Fixes: c1d6dd5d03eb ("wifi: mt76: mt7996: Add mt7996_mcu_teardown_mld_sta rouine") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-6-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 016b7e02d969d..5f90a385b4d38 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -1197,13 +1197,13 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + mt7996_mac_twt_teardown_flow(dev, link, + msta_link, i); + +- if (sta->mlo && links == BIT(link_id)) /* last link */ +- mt7996_mcu_teardown_mld_sta(dev, link, +- msta_link); +- else ++ if (!sta->mlo) + mt7996_mcu_add_sta(dev, link_conf, link_sta, + link, msta_link, + CONN_STATE_DISCONNECT, false); ++ else if (sta->mlo && links == BIT(link_id)) /* last link */ ++ mt7996_mcu_teardown_mld_sta(dev, link, ++ msta_link); + msta_link->wcid.sta_disabled = 1; + msta_link->wcid.sta = 0; + links = links & ~BIT(link_id); +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch b/queue-6.17/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch new file mode 100644 index 0000000000..e93a99f33f --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch @@ -0,0 +1,38 @@ +From f6a78865d21c869b3c86d76a5a76cd86a6a24064 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:02 +0800 +Subject: wifi: mt76: mt7996: fix using wrong phy to start in + mt7996_mac_restart() + +From: Shayne Chen + +[ Upstream commit f1e9f369ae42ee433836b24467e645192d046a51 ] + +Pass the correct mt7996_phy to mt7996_run(). + +Fixes: 0a5df0ec47f7 ("wifi: mt76: mt7996: remove redundant per-phy mac80211 calls during restart") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-11-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 30e2ef1404b90..b0092794f37c9 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -1894,7 +1894,7 @@ mt7996_mac_restart(struct mt7996_dev *dev) + if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) + continue; + +- ret = mt7996_run(&dev->phy); ++ ret = mt7996_run(phy); + if (ret) + goto out; + } +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch b/queue-6.17/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch new file mode 100644 index 0000000000..1b467284e3 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch @@ -0,0 +1,82 @@ +From e691dc930134151c23dbfa4f724e358394a4f766 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:16:21 +0100 +Subject: wifi: mt76: mt7996: grab mt76 mutex in mt7996_mac_sta_event() + +From: Lorenzo Bianconi + +[ Upstream commit 5a4bcba26e9fbea87507a81ad891e70bb525014f ] + +Grab mt76 mutex in mt7996_mac_sta_event routine in order to rely on +mt76_dereference() utility macro. + +Fixes: ecd72f9695e7e ("wifi: mt76: mt7996: Support MLO in mt7996_mac_sta_event()") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251114-mt76-fix-missing-mtx-v1-1-259ebf11f654@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 14e90ecf925e1..04b1d5f871376 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -1140,12 +1140,15 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + unsigned long links = sta->valid_links; + struct ieee80211_link_sta *link_sta; + unsigned int link_id; ++ int err = 0; ++ ++ mutex_lock(&dev->mt76.mutex); + + for_each_sta_active_link(vif, sta, link_sta, link_id) { + struct ieee80211_bss_conf *link_conf; + struct mt7996_sta_link *msta_link; + struct mt7996_vif_link *link; +- int i, err; ++ int i; + + link_conf = link_conf_dereference_protected(vif, link_id); + if (!link_conf) +@@ -1165,12 +1168,12 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + link, msta_link, + CONN_STATE_CONNECT, true); + if (err) +- return err; ++ goto unlock; + + err = mt7996_mcu_add_rate_ctrl(dev, msta_link->sta, vif, + link_id, false); + if (err) +- return err; ++ goto unlock; + + msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; + break; +@@ -1179,7 +1182,7 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + link, msta_link, + CONN_STATE_PORT_SECURE, false); + if (err) +- return err; ++ goto unlock; + break; + case MT76_STA_EVENT_DISASSOC: + for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) +@@ -1199,8 +1202,10 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + break; + } + } ++unlock: ++ mutex_unlock(&dev->mt76.mutex); + +- return 0; ++ return err; + } + + static void +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch b/queue-6.17/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch new file mode 100644 index 0000000000..5af212d995 --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch @@ -0,0 +1,45 @@ +From 19d35f39b113b7f86fa0baa56df856a8b1e10c7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:58 +0800 +Subject: wifi: mt76: mt7996: set link_valid field when initializing wcid + +From: Shayne Chen + +[ Upstream commit 7eaea3a8ba1e9bb58f87e3030f6ce18537e57e1f ] + +This ensures the upper layer uses the correct link ID during packet +processing. + +Fixes: dd82a9e02c05 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-7-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 5f90a385b4d38..b8bd2bda5172f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -346,6 +346,7 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + INIT_LIST_HEAD(&msta_link->rc_list); + msta_link->wcid.idx = idx; + msta_link->wcid.link_id = link_conf->link_id; ++ msta_link->wcid.link_valid = ieee80211_vif_is_mld(vif); + msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; + mt76_wcid_init(&msta_link->wcid, band_idx); + +@@ -969,6 +970,7 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev, + msta_link->wcid.sta = 1; + msta_link->wcid.idx = idx; + msta_link->wcid.link_id = link_id; ++ msta_link->wcid.link_valid = !!sta->valid_links; + msta_link->wcid.def_wcid = &msta->deflink.wcid; + + ewma_avg_signal_init(&msta_link->avg_ack_signal); +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch b/queue-6.17/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch new file mode 100644 index 0000000000..0d070a936a --- /dev/null +++ b/queue-6.17/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch @@ -0,0 +1,48 @@ +From 04a24fd43f59ce049bc916a861fb7132df249ec3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:16:24 +0100 +Subject: wifi: mt76: mt7996: skip deflink accounting for offchannel links + +From: Lorenzo Bianconi + +[ Upstream commit 4fe823b9ee0317b04ddc6d9e00fea892498aa0f2 ] + +Do not take into account offchannel links for deflink accounting. + +Fixes: a3316d2fc669f ("wifi: mt76: mt7996: set vif default link_id adding/removing vif links") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251114-mt76-fix-missing-mtx-v1-4-259ebf11f654@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 04b1d5f871376..1bd0214a01b0e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -372,7 +372,8 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + + ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, NULL); + +- if (mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) ++ if (!mlink->wcid->offchannel && ++ mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) + mvif->mt76.deflink_id = link_conf->link_id; + + return 0; +@@ -397,7 +398,8 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, + + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); + +- if (mvif->mt76.deflink_id == link_conf->link_id) { ++ if (!mlink->wcid->offchannel && ++ mvif->mt76.deflink_id == link_conf->link_id) { + struct ieee80211_bss_conf *iter; + unsigned int link_id; + +-- +2.51.0 + diff --git a/queue-6.17/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch b/queue-6.17/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch new file mode 100644 index 0000000000..bbb2180882 --- /dev/null +++ b/queue-6.17/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch @@ -0,0 +1,175 @@ +From d2cf0bc87681e61aa9120a9eaa1d69a8aabb4d77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 12:41:48 +0200 +Subject: wifi: mt76: wed: use proper wed reference in mt76 wed driver + callabacks + +From: Lorenzo Bianconi + +[ Upstream commit 385aab8fccd7a8746b9f1a17f3c1e38498a14bc7 ] + +MT7996 driver can use both wed and wed_hif2 devices to offload traffic +from/to the wireless NIC. In the current codebase we assume to always +use the primary wed device in wed callbacks resulting in the following +crash if the hw runs wed_hif2 (e.g. 6GHz link). + +[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a +[ 297.464928] Mem abort info: +[ 297.467722] ESR = 0x0000000096000005 +[ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits +[ 297.476766] SET = 0, FnV = 0 +[ 297.479809] EA = 0, S1PTW = 0 +[ 297.482940] FSC = 0x05: level 1 translation fault +[ 297.487809] Data abort info: +[ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 +[ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000 +[ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000 +[ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP +[ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0 +[ 297.723908] Tainted: [O]=OOT_MODULE +[ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT) +[ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table] +[ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80 +[ 297.757126] sp : ffffffc080fe3ae0 +[ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7 +[ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00 +[ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018 +[ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000 +[ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000 +[ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da +[ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200 +[ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002 +[ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000 +[ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8 +[ 297.831686] Call trace: +[ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.839254] mtk_wed_flow_remove+0x58/0x80 +[ 297.843342] mtk_flow_offload_cmd+0x434/0x574 +[ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40 +[ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table] +[ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table] +[ 297.864463] process_one_work+0x174/0x300 +[ 297.868465] worker_thread+0x278/0x430 +[ 297.872204] kthread+0xd8/0xdc +[ 297.875251] ret_from_fork+0x10/0x20 +[ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421) +[ 297.884901] ---[ end trace 0000000000000000 ]--- + +Fix the issue detecting the proper wed reference to use running wed +callabacks. + +Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support") +Tested-by: Daniel Pawlik +Tested-by: Matteo Croce +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 9 +++++++++ + drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 1 + + drivers/net/wireless/mediatek/mt76/wed.c | 10 +++++----- + include/linux/soc/mediatek/mtk_wed.h | 1 + + 4 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index 47c143e6a79af..eba26875aded6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -1226,6 +1226,15 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, + #define mt76_dereference(p, dev) \ + rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) + ++static inline struct mt76_dev *mt76_wed_to_dev(struct mtk_wed_device *wed) ++{ ++#ifdef CONFIG_NET_MEDIATEK_SOC_WED ++ if (wed->wlan.hif2) ++ return container_of(wed, struct mt76_dev, mmio.wed_hif2); ++#endif /* CONFIG_NET_MEDIATEK_SOC_WED */ ++ return container_of(wed, struct mt76_dev, mmio.wed); ++} ++ + static inline struct mt76_wcid * + __mt76_wcid_ptr(struct mt76_dev *dev, u16 idx) + { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +index 30b40f4a91be8..b2af25aef762b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +@@ -562,6 +562,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr, + + wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE; + wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf; ++ wed->wlan.hif2 = hif2; + + wed->wlan.amsdu_max_subframes = 8; + wed->wlan.amsdu_max_len = 1536; +diff --git a/drivers/net/wireless/mediatek/mt76/wed.c b/drivers/net/wireless/mediatek/mt76/wed.c +index 63f69e152b1cb..3ff547e0b2504 100644 +--- a/drivers/net/wireless/mediatek/mt76/wed.c ++++ b/drivers/net/wireless/mediatek/mt76/wed.c +@@ -8,7 +8,7 @@ + + void mt76_wed_release_rx_buf(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + int i; + + for (i = 0; i < dev->rx_token_size; i++) { +@@ -31,8 +31,8 @@ EXPORT_SYMBOL_GPL(mt76_wed_release_rx_buf); + #ifdef CONFIG_NET_MEDIATEK_SOC_WED + u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); + struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc; ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; + struct mt76_txwi_cache *t = NULL; + int i; +@@ -80,7 +80,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_init_rx_buf); + + int mt76_wed_offload_enable(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + spin_lock_bh(&dev->token_lock); + dev->token_size = wed->wlan.token_start; +@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_dma_setup); + + void mt76_wed_offload_disable(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + spin_lock_bh(&dev->token_lock); + dev->token_size = dev->drv->token_size; +@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_offload_disable); + + void mt76_wed_reset_complete(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + complete(&dev->mmio.wed_reset_complete); + } +diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h +index d8949a4ed0dc9..8d34bee714e8c 100644 +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -154,6 +154,7 @@ struct mtk_wed_device { + bool wcid_512; + bool hw_rro; + bool msi; ++ bool hif2; + + u16 token_start; + unsigned int nbuf; +-- +2.51.0 + diff --git a/queue-6.17/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-6.17/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..a70676878f --- /dev/null +++ b/queue-6.17/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 20a9b2a455f9c7fcacb7d2f251457e0becd66a45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index 2905baea62390..070c0431c4821 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-6.17/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-6.17/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..293423c135 --- /dev/null +++ b/queue-6.17/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From 398a525eb281ed7010feded55eb3c0c73b8d70d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index 0c5c66401daa6..7aa2da0cd63cc 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-6.17/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch b/queue-6.17/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch new file mode 100644 index 0000000000..7aecf586b6 --- /dev/null +++ b/queue-6.17/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch @@ -0,0 +1,54 @@ +From 450480ca8f635c81d065f7a162332318f313df71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 16:57:09 +0300 +Subject: wifi: rtw89: usb: fix leak in rtw89_usb_write_port() + +From: Fedor Pchelkin + +[ Upstream commit 7543818e97d5d54b3b2f75f1c4dedee298d7d914 ] + +When there is an attempt to write data and RTW89_FLAG_UNPLUGGED is set, +this means device is disconnected and no urb is submitted. Return +appropriate error code to the caller to properly free the allocated +resources. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") +Acked-by: Ping-Ke Shih +Signed-off-by: Fedor Pchelkin +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251104135720.321110-3-pchelkin@ispras.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/usb.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c +index e8e064cf7e0ad..512a46dd9d06a 100644 +--- a/drivers/net/wireless/realtek/rtw89/usb.c ++++ b/drivers/net/wireless/realtek/rtw89/usb.c +@@ -256,7 +256,7 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma, + int ret; + + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) +- return 0; ++ return -ENODEV; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) +@@ -305,8 +305,9 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) + ret = rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len, + txcb); + if (ret) { +- rtw89_err(rtwdev, "write port txch %d failed: %d\n", +- txch, ret); ++ if (ret != -ENODEV) ++ rtw89_err(rtwdev, "write port txch %d failed: %d\n", ++ txch, ret); + + skb_dequeue(&txcb->tx_ack_queue); + kfree(txcb); +-- +2.51.0 + diff --git a/queue-6.17/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch b/queue-6.17/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch new file mode 100644 index 0000000000..1044003c49 --- /dev/null +++ b/queue-6.17/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch @@ -0,0 +1,59 @@ +From 236d39b4df4eedfd29731a4963a349a825d0af94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 16:57:08 +0300 +Subject: wifi: rtw89: usb: use common error path for skbs in + rtw89_usb_rx_handler() + +From: Fedor Pchelkin + +[ Upstream commit 28a45575289f3292aa9cb7bacae18ba3ee7a6adf ] + +Allow adding rx_skb to rx_free_queue for later reuse on the common error +handling path, otherwise free it. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") +Acked-by: Ping-Ke Shih +Signed-off-by: Fedor Pchelkin +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251104135720.321110-2-pchelkin@ispras.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/usb.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c +index 6cf89aee252ed..e8e064cf7e0ad 100644 +--- a/drivers/net/wireless/realtek/rtw89/usb.c ++++ b/drivers/net/wireless/realtek/rtw89/usb.c +@@ -410,8 +410,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW89_USB_MAX_RXQ_LEN) { + rtw89_warn(rtwdev, "rx_queue overflow\n"); +- dev_kfree_skb_any(rx_skb); +- continue; ++ goto free_or_reuse; + } + + memset(&desc_info, 0, sizeof(desc_info)); +@@ -422,7 +421,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "failed to allocate RX skb of size %u\n", + desc_info.pkt_size); +- continue; ++ goto free_or_reuse; + } + + pkt_offset = desc_info.offset + desc_info.rxd_len; +@@ -432,6 +431,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + + rtw89_core_rx(rtwdev, &desc_info, skb); + ++free_or_reuse: + if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM) + dev_kfree_skb_any(rx_skb); + else +-- +2.51.0 + diff --git a/queue-6.17/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch b/queue-6.17/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch new file mode 100644 index 0000000000..9341fd4147 --- /dev/null +++ b/queue-6.17/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch @@ -0,0 +1,87 @@ +From 5c8da89f0bdd2f9c0374ef6a07b4e7210bbc64c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:22 +0000 +Subject: x86/boot: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit eb2266312507d7b757859e2227aa5c4ba6280ebe ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags. Bits above the + physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The PGD entry is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Acked-by: Dave Hansen +Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index bdd26050dff77..0e89e197e1126 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include "../string.h" + #include "efi.h" +@@ -168,9 +169,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * For 4- to 5-level paging transition, set up current CR3 as + * the first and the only entry in a new top-level page table. + */ +- *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; ++ *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; + } else { +- unsigned long src; ++ u64 *new_cr3; ++ pgd_t *pgdp; + + /* + * For 5- to 4-level paging transition, copy page table pointed +@@ -180,8 +182,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * We cannot just point to the page table from trampoline as it + * may be above 4G. + */ +- src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; +- memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); ++ pgdp = (pgd_t *)native_read_cr3_pa(); ++ new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); ++ memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); + } + + toggle_la57(trampoline_32bit); +-- +2.51.0 + diff --git a/queue-6.17/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-6.17/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..4f242d4db1 --- /dev/null +++ b/queue-6.17/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From 29d4c249e8b95279c7641a0d14bbab5c0edf8714 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 71ee20102a8af..b10684dedc589 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -181,8 +181,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -303,6 +303,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-6.18/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch b/queue-6.18/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch new file mode 100644 index 0000000000..296ddbfb06 --- /dev/null +++ b/queue-6.18/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch @@ -0,0 +1,60 @@ +From bbdc5470a889188300cb5c68292fad401cfea366 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 16:30:53 -0600 +Subject: 9p: fix cache/debug options printing in v9fs_show_options + +From: Eric Sandeen + +[ Upstream commit f0445613314f474c1a0ec6fa8a5cd153a618f1b6 ] + +commit 4eb3117888a92 changed the cache= option to accept either string +shortcuts or bitfield values. It also changed /proc/mounts to emit the +option as the hexadecimal numeric value rather than the shortcut string. + +However, by printing "cache=%x" without the leading 0x, shortcuts such +as "cache=loose" will emit "cache=f" and 'f' is not a string that is +parseable by kstrtoint(), so remounting may fail if a remount with +"cache=f" is attempted. + +debug=%x has had the same problem since options have been displayed in +c4fac9100456 ("9p: Implement show_options") + +Fix these by adding the 0x prefix to the hexadecimal value shown in +/proc/mounts. + +Fixes: 4eb3117888a92 ("fs/9p: Rework cache modes and add new options to Documentation") +Signed-off-by: Eric Sandeen +Message-ID: <54b93378-dcf1-4b04-922d-c8b4393da299@redhat.com> +[Dominique: use %#x at Al Viro's suggestion, also handle debug] +Tested-by: Remi Pommarel +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/v9fs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c +index a020a8f00a1ac..bde3ffb0e319a 100644 +--- a/fs/9p/v9fs.c ++++ b/fs/9p/v9fs.c +@@ -101,7 +101,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; + + if (v9ses->debug) +- seq_printf(m, ",debug=%x", v9ses->debug); ++ seq_printf(m, ",debug=%#x", v9ses->debug); + if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) + seq_printf(m, ",dfltuid=%u", + from_kuid_munged(&init_user_ns, v9ses->dfltuid)); +@@ -117,7 +117,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + if (v9ses->nodev) + seq_puts(m, ",nodevmap"); + if (v9ses->cache) +- seq_printf(m, ",cache=%x", v9ses->cache); ++ seq_printf(m, ",cache=%#x", v9ses->cache); + #ifdef CONFIG_9P_FSCACHE + if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE)) + seq_printf(m, ",cachetag=%s", v9ses->cachetag); +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-call-dma_buf_vmap_unlocked-for-importe.patch b/queue-6.18/accel-amdxdna-call-dma_buf_vmap_unlocked-for-importe.patch new file mode 100644 index 0000000000..71fbeb4e3f --- /dev/null +++ b/queue-6.18/accel-amdxdna-call-dma_buf_vmap_unlocked-for-importe.patch @@ -0,0 +1,153 @@ +From de4348e91bf0ac07847b956b0cf36c54b879a028 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 10:48:42 -0700 +Subject: accel/amdxdna: Call dma_buf_vmap_unlocked() for imported object + +From: Lizhi Hou + +[ Upstream commit 457f4393d02fdb612a93912fb09cef70e6e545c9 ] + +In amdxdna_gem_obj_vmap(), calling dma_buf_vmap() triggers a kernel +warning if LOCKDEP is enabled. So for imported object, use +dma_buf_vmap_unlocked(). Then, use drm_gem_vmap() for other objects. +The similar change applies to vunmap code. + +Fixes: bd72d4acda10 ("accel/amdxdna: Support user space allocated buffer") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://lore.kernel.org/r/20250916174842.234709-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/amdxdna_gem.c | 47 ++++++++++++----------------- + 1 file changed, 20 insertions(+), 27 deletions(-) + +diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c +index d407a36eb4126..7f91863c3f24c 100644 +--- a/drivers/accel/amdxdna/amdxdna_gem.c ++++ b/drivers/accel/amdxdna/amdxdna_gem.c +@@ -392,35 +392,33 @@ static const struct dma_buf_ops amdxdna_dmabuf_ops = { + .vunmap = drm_gem_dmabuf_vunmap, + }; + +-static int amdxdna_gem_obj_vmap(struct drm_gem_object *obj, struct iosys_map *map) ++static int amdxdna_gem_obj_vmap(struct amdxdna_gem_obj *abo, void **vaddr) + { +- struct amdxdna_gem_obj *abo = to_xdna_obj(obj); +- +- iosys_map_clear(map); +- +- dma_resv_assert_held(obj->resv); ++ struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); ++ int ret; + + if (is_import_bo(abo)) +- dma_buf_vmap(abo->dma_buf, map); ++ ret = dma_buf_vmap_unlocked(abo->dma_buf, &map); + else +- drm_gem_shmem_object_vmap(obj, map); +- +- if (!map->vaddr) +- return -ENOMEM; ++ ret = drm_gem_vmap(to_gobj(abo), &map); + +- return 0; ++ *vaddr = map.vaddr; ++ return ret; + } + +-static void amdxdna_gem_obj_vunmap(struct drm_gem_object *obj, struct iosys_map *map) ++static void amdxdna_gem_obj_vunmap(struct amdxdna_gem_obj *abo) + { +- struct amdxdna_gem_obj *abo = to_xdna_obj(obj); ++ struct iosys_map map; ++ ++ if (!abo->mem.kva) ++ return; + +- dma_resv_assert_held(obj->resv); ++ iosys_map_set_vaddr(&map, abo->mem.kva); + + if (is_import_bo(abo)) +- dma_buf_vunmap(abo->dma_buf, map); ++ dma_buf_vunmap_unlocked(abo->dma_buf, &map); + else +- drm_gem_shmem_object_vunmap(obj, map); ++ drm_gem_vunmap(to_gobj(abo), &map); + } + + static struct dma_buf *amdxdna_gem_prime_export(struct drm_gem_object *gobj, int flags) +@@ -455,7 +453,6 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj) + { + struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); + struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); +- struct iosys_map map = IOSYS_MAP_INIT_VADDR(abo->mem.kva); + + XDNA_DBG(xdna, "BO type %d xdna_addr 0x%llx", abo->type, abo->mem.dev_addr); + +@@ -468,7 +465,7 @@ static void amdxdna_gem_obj_free(struct drm_gem_object *gobj) + if (abo->type == AMDXDNA_BO_DEV_HEAP) + drm_mm_takedown(&abo->mm); + +- drm_gem_vunmap(gobj, &map); ++ amdxdna_gem_obj_vunmap(abo); + mutex_destroy(&abo->lock); + + if (is_import_bo(abo)) { +@@ -489,8 +486,8 @@ static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = { + .pin = drm_gem_shmem_object_pin, + .unpin = drm_gem_shmem_object_unpin, + .get_sg_table = drm_gem_shmem_object_get_sg_table, +- .vmap = amdxdna_gem_obj_vmap, +- .vunmap = amdxdna_gem_obj_vunmap, ++ .vmap = drm_gem_shmem_object_vmap, ++ .vunmap = drm_gem_shmem_object_vunmap, + .mmap = amdxdna_gem_obj_mmap, + .vm_ops = &drm_gem_shmem_vm_ops, + .export = amdxdna_gem_prime_export, +@@ -663,7 +660,6 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev, + struct drm_file *filp) + { + struct amdxdna_client *client = filp->driver_priv; +- struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); + struct amdxdna_dev *xdna = to_xdna_dev(dev); + struct amdxdna_gem_obj *abo; + int ret; +@@ -692,12 +688,11 @@ amdxdna_drm_create_dev_heap(struct drm_device *dev, + abo->mem.dev_addr = client->xdna->dev_info->dev_mem_base; + drm_mm_init(&abo->mm, abo->mem.dev_addr, abo->mem.size); + +- ret = drm_gem_vmap(to_gobj(abo), &map); ++ ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); + if (ret) { + XDNA_ERR(xdna, "Vmap heap bo failed, ret %d", ret); + goto release_obj; + } +- abo->mem.kva = map.vaddr; + + client->dev_heap = abo; + drm_gem_object_get(to_gobj(abo)); +@@ -748,7 +743,6 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, + struct amdxdna_drm_create_bo *args, + struct drm_file *filp) + { +- struct iosys_map map = IOSYS_MAP_INIT_VADDR(NULL); + struct amdxdna_dev *xdna = to_xdna_dev(dev); + struct amdxdna_gem_obj *abo; + int ret; +@@ -770,12 +764,11 @@ amdxdna_drm_create_cmd_bo(struct drm_device *dev, + abo->type = AMDXDNA_BO_CMD; + abo->client = filp->driver_priv; + +- ret = drm_gem_vmap(to_gobj(abo), &map); ++ ret = amdxdna_gem_obj_vmap(abo, &abo->mem.kva); + if (ret) { + XDNA_ERR(xdna, "Vmap cmd bo failed, ret %d", ret); + goto release_obj; + } +- abo->mem.kva = map.vaddr; + + return abo; + +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch b/queue-6.18/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch new file mode 100644 index 0000000000..612ba2f14c --- /dev/null +++ b/queue-6.18/accel-amdxdna-clear-mailbox-interrupt-register-durin.patch @@ -0,0 +1,40 @@ +From 5c94998e883de11e58c1b59c877d39790c71f254 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 10:11:15 -0800 +Subject: accel/amdxdna: Clear mailbox interrupt register during channel + creation + +From: Lizhi Hou + +[ Upstream commit 6ff9385c07aa311f01f87307e6256231be7d8675 ] + +The mailbox interrupt register is not always cleared when a mailbox channel +is created. This can leave stale interrupt states from previous operations. + +Fix this by explicitly clearing the interrupt register in the mailbox +channel creation function. + +Fixes: b87f920b9344 ("accel/amdxdna: Support hardware mailbox") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251107181115.1293158-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/amdxdna_mailbox.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/accel/amdxdna/amdxdna_mailbox.c b/drivers/accel/amdxdna/amdxdna_mailbox.c +index da1ac89bb78f1..6634a4d5717ff 100644 +--- a/drivers/accel/amdxdna/amdxdna_mailbox.c ++++ b/drivers/accel/amdxdna/amdxdna_mailbox.c +@@ -513,6 +513,7 @@ xdna_mailbox_create_channel(struct mailbox *mb, + } + + mb_chann->bad_state = false; ++ mailbox_reg_write(mb_chann, mb_chann->iohub_int_addr, 0); + + MB_DBG(mb_chann, "Mailbox channel created (irq: %d)", mb_chann->msix_irq); + return mb_chann; +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-fix-an-integer-overflow-in-aie2_query_.patch b/queue-6.18/accel-amdxdna-fix-an-integer-overflow-in-aie2_query_.patch new file mode 100644 index 0000000000..a3f6f89806 --- /dev/null +++ b/queue-6.18/accel-amdxdna-fix-an-integer-overflow-in-aie2_query_.patch @@ -0,0 +1,51 @@ +From c2ef59f2139984f8431d894f3b6bd39d5c2f135b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Sep 2025 08:45:31 -0700 +Subject: accel/amdxdna: Fix an integer overflow in + aie2_query_ctx_status_array() + +From: Lizhi Hou + +[ Upstream commit 9e16c8bf9aebf629344cfd4cd5e3dc7d8c3f7d82 ] + +The unpublished smatch static checker reported a warning. + +drivers/accel/amdxdna/aie2_pci.c:904 aie2_query_ctx_status_array() +warn: potential user controlled sizeof overflow +'args->num_element * args->element_size' '1-u32max(user) * 1-u32max(user)' + +Even this will not cause a real issue, it is better to put a reasonable +limitation for element_size and num_element. Add condition to make sure +the input element_size <= 4K and num_element <= 1K. + +Reported-by: Dan Carpenter +Closes: https://lore.kernel.org/dri-devel/aL56ZCLyl3tLQM1e@stanley.mountain/ +Fixes: 2f509fe6a42c ("accel/amdxdna: Add ioctl DRM_IOCTL_AMDXDNA_GET_ARRAY") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://lore.kernel.org/r/20250909154531.3469979-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_pci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c +index 87c425e3d2b99..6e39c769bb6d8 100644 +--- a/drivers/accel/amdxdna/aie2_pci.c ++++ b/drivers/accel/amdxdna/aie2_pci.c +@@ -898,6 +898,12 @@ static int aie2_query_ctx_status_array(struct amdxdna_client *client, + + drm_WARN_ON(&xdna->ddev, !mutex_is_locked(&xdna->dev_lock)); + ++ if (args->element_size > SZ_4K || args->num_element > SZ_1K) { ++ XDNA_DBG(xdna, "Invalid element size %d or number of element %d", ++ args->element_size, args->num_element); ++ return -EINVAL; ++ } ++ + array_args.element_size = min(args->element_size, + sizeof(struct amdxdna_drm_hwctx_entry)); + array_args.buffer = args->buffer; +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch b/queue-6.18/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch new file mode 100644 index 0000000000..32e0a2b29f --- /dev/null +++ b/queue-6.18/accel-amdxdna-fix-deadlock-between-context-destroy-a.patch @@ -0,0 +1,54 @@ +From 639a95356806a6b7c17f10dd277464d85e773330 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 10:10:50 -0800 +Subject: accel/amdxdna: Fix deadlock between context destroy and job timeout + +From: Lizhi Hou + +[ Upstream commit ca2583412306ceda9304a7c4302fd9efbf43e963 ] + +Hardware context destroy function holds dev_lock while waiting for all jobs +to complete. The timeout job also needs to acquire dev_lock, this leads to +a deadlock. + +Fix the issue by temporarily releasing dev_lock before waiting for all +jobs to finish, and reacquiring it afterward. + +Fixes: 4fd6ca90fc7f ("accel/amdxdna: Refactor hardware context destroy routine") +Reviewed-by: Maciej Falkowski +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251107181050.1293125-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index 2e479a8d86c31..75246c481fa50 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -681,17 +681,19 @@ void aie2_hwctx_fini(struct amdxdna_hwctx *hwctx) + ndev->hwctx_num--; + + XDNA_DBG(xdna, "%s sequence number %lld", hwctx->name, hwctx->priv->seq); +- drm_sched_entity_destroy(&hwctx->priv->entity); +- + aie2_hwctx_wait_for_idle(hwctx); + + /* Request fw to destroy hwctx and cancel the rest pending requests */ + aie2_release_resource(hwctx); + ++ mutex_unlock(&xdna->dev_lock); ++ drm_sched_entity_destroy(&hwctx->priv->entity); ++ + /* Wait for all submitted jobs to be completed or canceled */ + wait_event(hwctx->priv->job_free_wq, + atomic64_read(&hwctx->job_submit_cnt) == + atomic64_read(&hwctx->job_free_cnt)); ++ mutex_lock(&xdna->dev_lock); + + drm_sched_fini(&hwctx->priv->sched); + aie2_ctx_syncobj_destroy(hwctx); +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch b/queue-6.18/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch new file mode 100644 index 0000000000..8625a99756 --- /dev/null +++ b/queue-6.18/accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch @@ -0,0 +1,51 @@ +From 1a4aaca94b156adb949d0513919cf1aa007e9d35 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 11:41:40 -0800 +Subject: accel/amdxdna: Fix dma_fence leak when job is canceled + +From: Lizhi Hou + +[ Upstream commit dea9f84776b96a703f504631ebe9fea07bd2c181 ] + +Currently, dma_fence_put(job->fence) is called in job notification +callback. However, if a job is canceled, the notification callback is never +invoked, leading to a memory leak. Move dma_fence_put(job->fence) +to the job cleanup function to ensure the fence is always released. + +Fixes: aac243092b70 ("accel/amdxdna: Add command execution") +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251105194140.1004314-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 1 - + drivers/accel/amdxdna/amdxdna_ctx.c | 1 + + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index c9f712f0ec00c..2e479a8d86c31 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -189,7 +189,6 @@ aie2_sched_notify(struct amdxdna_sched_job *job) + + up(&job->hwctx->priv->job_sem); + job->job_done = true; +- dma_fence_put(fence); + mmput_async(job->mm); + aie2_job_put(job); + } +diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c +index 4bfe4ef20550f..856fb25086f12 100644 +--- a/drivers/accel/amdxdna/amdxdna_ctx.c ++++ b/drivers/accel/amdxdna/amdxdna_ctx.c +@@ -389,6 +389,7 @@ void amdxdna_sched_job_cleanup(struct amdxdna_sched_job *job) + trace_amdxdna_debug_point(job->hwctx->name, job->seq, "job release"); + amdxdna_arg_bos_put(job); + amdxdna_gem_put_obj(job->cmd_bo); ++ dma_fence_put(job->fence); + } + + int amdxdna_cmd_submit(struct amdxdna_client *client, +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch b/queue-6.18/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch new file mode 100644 index 0000000000..fccecad5d5 --- /dev/null +++ b/queue-6.18/accel-amdxdna-fix-incorrect-command-state-for-timed-.patch @@ -0,0 +1,80 @@ +From e4f0d885f0fcb43a80146e54b5b80a4242aafaab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 12:34:23 -0700 +Subject: accel/amdxdna: Fix incorrect command state for timed out job + +From: Lizhi Hou + +[ Upstream commit 6fb7f298883246e21f60f971065adcb789ae6eba ] + +When a command times out, mark it as ERT_CMD_STATE_TIMEOUT. Any other +commands that are canceled due to this timeout should be marked as +ERT_CMD_STATE_ABORT. + +Fixes: aac243092b70 ("accel/amdxdna: Add command execution") +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251029193423.2430463-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_ctx.c | 15 +++++++++++++-- + drivers/accel/amdxdna/amdxdna_ctx.h | 1 + + 2 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/amdxdna/aie2_ctx.c b/drivers/accel/amdxdna/aie2_ctx.c +index e9f9b1fa5dc1b..c9f712f0ec00c 100644 +--- a/drivers/accel/amdxdna/aie2_ctx.c ++++ b/drivers/accel/amdxdna/aie2_ctx.c +@@ -204,10 +204,13 @@ aie2_sched_resp_handler(void *handle, void __iomem *data, size_t size) + + cmd_abo = job->cmd_bo; + +- if (unlikely(!data)) ++ if (unlikely(job->job_timeout)) { ++ amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); ++ ret = -EINVAL; + goto out; ++ } + +- if (unlikely(size != sizeof(u32))) { ++ if (unlikely(!data) || unlikely(size != sizeof(u32))) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + ret = -EINVAL; + goto out; +@@ -260,6 +263,13 @@ aie2_sched_cmdlist_resp_handler(void *handle, void __iomem *data, size_t size) + int ret = 0; + + cmd_abo = job->cmd_bo; ++ ++ if (unlikely(job->job_timeout)) { ++ amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_TIMEOUT); ++ ret = -EINVAL; ++ goto out; ++ } ++ + if (unlikely(!data) || unlikely(size != sizeof(u32) * 3)) { + amdxdna_cmd_set_state(cmd_abo, ERT_CMD_STATE_ABORT); + ret = -EINVAL; +@@ -362,6 +372,7 @@ aie2_sched_job_timedout(struct drm_sched_job *sched_job) + + xdna = hwctx->client->xdna; + trace_xdna_job(sched_job, hwctx->name, "job timedout", job->seq); ++ job->job_timeout = true; + mutex_lock(&xdna->dev_lock); + aie2_hwctx_stop(xdna, hwctx, sched_job); + +diff --git a/drivers/accel/amdxdna/amdxdna_ctx.h b/drivers/accel/amdxdna/amdxdna_ctx.h +index 7cd7a55936f09..8c1d181df6e79 100644 +--- a/drivers/accel/amdxdna/amdxdna_ctx.h ++++ b/drivers/accel/amdxdna/amdxdna_ctx.h +@@ -105,6 +105,7 @@ struct amdxdna_sched_job { + /* user can wait on this fence */ + struct dma_fence *out_fence; + bool job_done; ++ bool job_timeout; + u64 seq; + struct amdxdna_gem_obj *cmd_bo; + size_t bo_cnt; +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-fix-uninitialized-return-value.patch b/queue-6.18/accel-amdxdna-fix-uninitialized-return-value.patch new file mode 100644 index 0000000000..9f4978f4a7 --- /dev/null +++ b/queue-6.18/accel-amdxdna-fix-uninitialized-return-value.patch @@ -0,0 +1,48 @@ +From c264c56b999d343a2eda1ca35bdc54b3085f7862 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 09:55:03 -0700 +Subject: accel/amdxdna: Fix uninitialized return value + +From: Lizhi Hou + +[ Upstream commit 81233d5419cf20e4f5ef505882951616888a2ef9 ] + +In aie2_get_hwctx_status() and aie2_query_ctx_status_array(), the +functions could return an uninitialized value in some cases. Update them +to always return 0. The amount of valid results is indicated by the +returned buffer_size, element_size, and num_element fields. + +Fixes: 2f509fe6a42c ("accel/amdxdna: Add ioctl DRM_IOCTL_AMDXDNA_GET_ARRAY") +Reviewed-by: Mario Limonciello (AMD) +Signed-off-by: Lizhi Hou +Link: https://patch.msgid.link/20251024165503.1548131-1-lizhi.hou@amd.com +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_pci.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c +index 6e39c769bb6d8..43f725e1a2d76 100644 +--- a/drivers/accel/amdxdna/aie2_pci.c ++++ b/drivers/accel/amdxdna/aie2_pci.c +@@ -845,7 +845,7 @@ static int aie2_get_hwctx_status(struct amdxdna_client *client, + } + + args->buffer_size -= (u32)(array_args.buffer - args->buffer); +- return ret; ++ return 0; + } + + static int aie2_get_info(struct amdxdna_client *client, struct amdxdna_drm_get_info *args) +@@ -920,7 +920,7 @@ static int aie2_query_ctx_status_array(struct amdxdna_client *client, + args->num_element = (u32)((array_args.buffer - args->buffer) / + args->element_size); + +- return ret; ++ return 0; + } + + static int aie2_get_array(struct amdxdna_client *client, +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch b/queue-6.18/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch new file mode 100644 index 0000000000..4086a2bc92 --- /dev/null +++ b/queue-6.18/accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch @@ -0,0 +1,51 @@ +From 6ffe796652083000b8940d715be45bd93a8c71e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 10:48:09 +0200 +Subject: accel/ivpu: Ensure rpm_runtime_put in case of engine reset/resume + fail + +From: Karol Wachowski + +[ Upstream commit 9f6c63285737b141ca25a619add80a96111b8b96 ] + +Previously, aborting work could return early after engine reset or resume +failure, skipping the necessary runtime_put cleanup leaving the device +with incorrect reference count breaking runtime power management state. + +Replace early returns with goto statements to ensure runtime_put is always +executed. + +Fixes: a47e36dc5d90 ("accel/ivpu: Trigger device recovery on engine reset/resume failure") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250916084809.850073-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_job.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index 060f1fc031d34..dbefa43c74e28 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -1012,7 +1012,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) + + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) + if (ivpu_jsm_reset_engine(vdev, 0)) +- return; ++ goto runtime_put; + + mutex_lock(&vdev->context_list_lock); + xa_for_each(&vdev->context_xa, ctx_id, file_priv) { +@@ -1036,7 +1036,7 @@ void ivpu_context_abort_work_fn(struct work_struct *work) + goto runtime_put; + + if (ivpu_jsm_hws_resume_engine(vdev, 0)) +- return; ++ goto runtime_put; + /* + * In hardware scheduling mode NPU already has stopped processing jobs + * and won't send us any further notifications, thus we have to free job related resources +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-fix-dct-active-percent-format.patch b/queue-6.18/accel-ivpu-fix-dct-active-percent-format.patch new file mode 100644 index 0000000000..1664644e8d --- /dev/null +++ b/queue-6.18/accel-ivpu-fix-dct-active-percent-format.patch @@ -0,0 +1,71 @@ +From faf256057c682ed96f363e387928d46b45edc8e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:43:22 +0200 +Subject: accel/ivpu: Fix DCT active percent format + +From: Karol Wachowski + +[ Upstream commit aa1c2b073ad23847dd2e7bdc7d30009f34ed7f59 ] + +The pcode MAILBOX STATUS register PARAM2 field expects DCT active +percent in U1.7 value format. Convert percentage value to this +format before writing to the register. + +Fixes: a19bffb10c46 ("accel/ivpu: Implement DCT handling") +Reviewed-by: Lizhi Hou +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20251001104322.1249896-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_hw_btrs.c | 2 +- + drivers/accel/ivpu/ivpu_hw_btrs.h | 2 +- + drivers/accel/ivpu/ivpu_pm.c | 9 +++++++-- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.c b/drivers/accel/ivpu/ivpu_hw_btrs.c +index afdb3b2aa72a7..aa33f562d29c1 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.c ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.c +@@ -752,7 +752,7 @@ int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable) + } + } + +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent) ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent) + { + u32 val = 0; + u32 cmd = enable ? DCT_ENABLE : DCT_DISABLE; +diff --git a/drivers/accel/ivpu/ivpu_hw_btrs.h b/drivers/accel/ivpu/ivpu_hw_btrs.h +index 032c384ac3d4d..c4c10e22f30f3 100644 +--- a/drivers/accel/ivpu/ivpu_hw_btrs.h ++++ b/drivers/accel/ivpu/ivpu_hw_btrs.h +@@ -36,7 +36,7 @@ u32 ivpu_hw_btrs_dpu_freq_get(struct ivpu_device *vdev); + bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq); + bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq); + int ivpu_hw_btrs_dct_get_request(struct ivpu_device *vdev, bool *enable); +-void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 active_percent); ++void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u8 active_percent); + u32 ivpu_hw_btrs_telemetry_offset_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_size_get(struct ivpu_device *vdev); + u32 ivpu_hw_btrs_telemetry_enable_get(struct ivpu_device *vdev); +diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c +index 475ddc94f1cfe..457ccf09df545 100644 +--- a/drivers/accel/ivpu/ivpu_pm.c ++++ b/drivers/accel/ivpu/ivpu_pm.c +@@ -502,6 +502,11 @@ void ivpu_pm_irq_dct_work_fn(struct work_struct *work) + else + ret = ivpu_pm_dct_disable(vdev); + +- if (!ret) +- ivpu_hw_btrs_dct_set_status(vdev, enable, vdev->pm->dct_active_percent); ++ if (!ret) { ++ /* Convert percent to U1.7 format */ ++ u8 val = DIV_ROUND_CLOSEST(vdev->pm->dct_active_percent * 128, 100); ++ ++ ivpu_hw_btrs_dct_set_status(vdev, enable, val); ++ } ++ + } +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch b/queue-6.18/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch new file mode 100644 index 0000000000..f625210492 --- /dev/null +++ b/queue-6.18/accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch @@ -0,0 +1,91 @@ +From fd415657b6504e3bb9e08ab80321b57cda694964 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 16:51:14 +0200 +Subject: accel/ivpu: Fix page fault in ivpu_bo_unbind_all_bos_from_context() + +From: Jacek Lawrynowicz + +[ Upstream commit 8b694b405a84696f1d964f6da7cf9721e68c4714 ] + +Don't add BO to the vdev->bo_list in ivpu_gem_create_object(). +When failure happens inside drm_gem_shmem_create(), the BO is not +fully created and ivpu_gem_bo_free() callback will not be called +causing a deleted BO to be left on the list. + +Fixes: 8d88e4cdce4f ("accel/ivpu: Use GEM shmem helper for all buffers") +Signed-off-by: Jacek Lawrynowicz +Signed-off-by: Maciej Falkowski +Reviewed-by: Karol Wachowski +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250925145114.1446283-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index dc6d0d15cda9c..171e809575ad6 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -193,7 +193,6 @@ void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_m + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size) + { +- struct ivpu_device *vdev = to_ivpu_device(dev); + struct ivpu_bo *bo; + + if (size == 0 || !PAGE_ALIGNED(size)) +@@ -208,20 +207,17 @@ struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t siz + + INIT_LIST_HEAD(&bo->bo_list_node); + +- mutex_lock(&vdev->bo_list_lock); +- list_add_tail(&bo->bo_list_node, &vdev->bo_list); +- mutex_unlock(&vdev->bo_list_lock); +- +- ivpu_dbg(vdev, BO, " alloc: bo %8p size %9zu\n", bo, size); + return &bo->base.base; + } + + struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + struct dma_buf *dma_buf) + { ++ struct ivpu_device *vdev = to_ivpu_device(dev); + struct device *attach_dev = dev->dev; + struct dma_buf_attachment *attach; + struct drm_gem_object *obj; ++ struct ivpu_bo *bo; + int ret; + + attach = dma_buf_attach(dma_buf, attach_dev); +@@ -239,6 +235,14 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + obj->import_attach = attach; + obj->resv = dma_buf->resv; + ++ bo = to_ivpu_bo(obj); ++ ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, "import: bo %8p size %9zu\n", bo, ivpu_bo_size(bo)); ++ + return obj; + + fail_detach: +@@ -269,6 +273,12 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla + bo->base.map_wc = flags & DRM_IVPU_BO_WC; + bo->flags = flags; + ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, " alloc: bo %8p size %9llu\n", bo, size); ++ + return bo; + } + +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch b/queue-6.18/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch new file mode 100644 index 0000000000..9854a8fd37 --- /dev/null +++ b/queue-6.18/accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch @@ -0,0 +1,45 @@ +From 8884d6f7728d4914057c15e6af31a6c9178f9ffe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 09:17:25 +0200 +Subject: accel/ivpu: Fix race condition when mapping dmabuf + +From: Wludzik, Jozef + +[ Upstream commit 63c7870fab67b2ab2bfe75e8b46f3c37b88c47a8 ] + +Fix a race that can occur when multiple jobs submit the same dmabuf. +This could cause the sg_table to be mapped twice, leading to undefined +behavior. + +Fixes: e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +Signed-off-by: Wludzik, Jozef +Reviewed-by: Jeff Hugo +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20251014071725.3047287-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 171e809575ad6..1fca969df19dc 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -45,12 +45,13 @@ static inline void ivpu_bo_unlock(struct ivpu_bo *bo) + + static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct ivpu_bo *bo) + { +- struct sg_table *sgt = bo->base.sgt; ++ struct sg_table *sgt; + + drm_WARN_ON(&vdev->drm, !bo->base.base.import_attach); + + ivpu_bo_lock(bo); + ++ sgt = bo->base.sgt; + if (!sgt) { + sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL); + if (IS_ERR(sgt)) +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-fix-race-condition-when-unbinding-bos.patch b/queue-6.18/accel-ivpu-fix-race-condition-when-unbinding-bos.patch new file mode 100644 index 0000000000..145ac99eac --- /dev/null +++ b/queue-6.18/accel-ivpu-fix-race-condition-when-unbinding-bos.patch @@ -0,0 +1,53 @@ +From fc86838a1f9dcc45a76ba716f9f7cc99c0467b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 08:14:51 +0100 +Subject: accel/ivpu: Fix race condition when unbinding BOs + +From: Tomasz Rusinowicz + +[ Upstream commit 00812636df370bedf4e44a0c81b86ea96bca8628 ] + +Fix 'Memory manager not clean during takedown' warning that occurs +when ivpu_gem_bo_free() removes the BO from the BOs list before it +gets unmapped. Then file_priv_unbind() triggers a warning in +drm_mm_takedown() during context teardown. + +Protect the unmapping sequence with bo_list_lock to ensure the BO is +always fully unmapped when removed from the list. This ensures the BO +is either fully unmapped at context teardown time or present on the +list and unmapped by file_priv_unbind(). + +Fixes: 48aea7f2a2ef ("accel/ivpu: Fix locking in ivpu_bo_remove_all_bos_from_context()") +Signed-off-by: Tomasz Rusinowicz +Reviewed-by: Jeff Hugo +Signed-off-by: Karol Wachowski +Link: https://patch.msgid.link/20251029071451.184243-1-karol.wachowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index a38e41f9c7123..fda0a18e6d639 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -314,7 +314,6 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + + mutex_lock(&vdev->bo_list_lock); + list_del(&bo->bo_list_node); +- mutex_unlock(&vdev->bo_list_lock); + + drm_WARN_ON(&vdev->drm, !drm_gem_is_imported(&bo->base.base) && + !dma_resv_test_signaled(obj->resv, DMA_RESV_USAGE_READ)); +@@ -325,6 +324,8 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + ivpu_bo_unbind_locked(bo); + ivpu_bo_unlock(bo); + ++ mutex_unlock(&vdev->bo_list_lock); ++ + drm_WARN_ON(&vdev->drm, bo->mmu_mapped); + drm_WARN_ON(&vdev->drm, bo->ctx); + +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch b/queue-6.18/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch new file mode 100644 index 0000000000..4cdee3b7a1 --- /dev/null +++ b/queue-6.18/accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch @@ -0,0 +1,44 @@ +From f9a1aed3f5b7ea10da4243aabf1b81a6623b8b7e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 16:09:32 +0100 +Subject: accel/ivpu: Remove skip of dma unmap for imported buffers + +From: Maciej Falkowski + +[ Upstream commit c063c1bbee67391f12956d2ffdd5da00eb87ff79 ] + +Rework of imported buffers introduced in the commit +e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +switched the logic of imported buffers by dma mapping/unmapping +them just as the regular buffers. + +The commit didn't include removal of skipping dma unmap of imported +buffers which results in them being mapped without unmapping. + +Fixes: e0c0891cd63b ("accel/ivpu: Rework bind/unbind of imported buffers") +Reviewed-by: Jeff Hugo +Reviewed-by: Karol Wachowski +Signed-off-by: Maciej Falkowski +Link: https://patch.msgid.link/20251027150933.2384538-1-maciej.falkowski@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 1fca969df19dc..a38e41f9c7123 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -157,9 +157,6 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + bo->ctx = NULL; + } + +- if (drm_gem_is_imported(&bo->base.base)) +- return; +- + if (bo->base.sgt) { + if (bo->base.base.import_attach) { + dma_buf_unmap_attachment(bo->base.base.import_attach, +-- +2.51.0 + diff --git a/queue-6.18/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch b/queue-6.18/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch new file mode 100644 index 0000000000..c875fbfccc --- /dev/null +++ b/queue-6.18/accel-ivpu-rework-bind-unbind-of-imported-buffers.patch @@ -0,0 +1,301 @@ +From ccb8079d1e712e45434702e7a6a8be5d3ce47ac4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 16:50:59 +0200 +Subject: accel/ivpu: Rework bind/unbind of imported buffers + +From: Jacek Lawrynowicz + +[ Upstream commit e0c0891cd63bf8338c25c423e28a5a93aed3d74c ] + +Ensure that imported buffers are properly mapped and unmapped in +the same way as regular buffers to properly handle buffers during +device's bind and unbind operations to prevent resource leaks and +inconsistent buffer states. + +Imported buffers are now dma_mapped before submission and +dma_unmapped in ivpu_bo_unbind(), guaranteeing they are unmapped +when the device is unbound. + +Add also imported buffers to vdev->bo_list for consistent unmapping +on device unbind. The bo->ctx_id is set in open() so imported +buffers have a valid context ID. + +Debug logs have been updated to match the new code structure. +The function ivpu_bo_pin() has been renamed to ivpu_bo_bind() +to better reflect its purpose, and unbind tests have been refactored +for improved coverage and clarity. + +Signed-off-by: Jacek Lawrynowicz +Signed-off-by: Maciej Falkowski +Reviewed-by: Karol Wachowski +Signed-off-by: Karol Wachowski +Link: https://lore.kernel.org/r/20250925145059.1446243-1-maciej.falkowski@linux.intel.com +Stable-dep-of: 8b694b405a84 ("accel/ivpu: Fix page fault in ivpu_bo_unbind_all_bos_from_context()") +Signed-off-by: Sasha Levin +--- + drivers/accel/ivpu/ivpu_gem.c | 90 ++++++++++++++++++++++------------- + drivers/accel/ivpu/ivpu_gem.h | 2 +- + drivers/accel/ivpu/ivpu_job.c | 2 +- + 3 files changed, 60 insertions(+), 34 deletions(-) + +diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c +index 59cfcf3eaded9..dc6d0d15cda9c 100644 +--- a/drivers/accel/ivpu/ivpu_gem.c ++++ b/drivers/accel/ivpu/ivpu_gem.c +@@ -27,8 +27,8 @@ static const struct drm_gem_object_funcs ivpu_gem_funcs; + static inline void ivpu_dbg_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, const char *action) + { + ivpu_dbg(vdev, BO, +- "%6s: bo %8p vpu_addr %9llx size %8zu ctx %d has_pages %d dma_mapped %d mmu_mapped %d wc %d imported %d\n", +- action, bo, bo->vpu_addr, ivpu_bo_size(bo), bo->ctx_id, ++ "%6s: bo %8p size %9zu ctx %d vpu_addr %9llx pages %d sgt %d mmu_mapped %d wc %d imported %d\n", ++ action, bo, ivpu_bo_size(bo), bo->ctx_id, bo->vpu_addr, + (bool)bo->base.pages, (bool)bo->base.sgt, bo->mmu_mapped, bo->base.map_wc, + (bool)drm_gem_is_imported(&bo->base.base)); + } +@@ -43,22 +43,46 @@ static inline void ivpu_bo_unlock(struct ivpu_bo *bo) + dma_resv_unlock(bo->base.base.resv); + } + ++static struct sg_table *ivpu_bo_map_attachment(struct ivpu_device *vdev, struct ivpu_bo *bo) ++{ ++ struct sg_table *sgt = bo->base.sgt; ++ ++ drm_WARN_ON(&vdev->drm, !bo->base.base.import_attach); ++ ++ ivpu_bo_lock(bo); ++ ++ if (!sgt) { ++ sgt = dma_buf_map_attachment(bo->base.base.import_attach, DMA_BIDIRECTIONAL); ++ if (IS_ERR(sgt)) ++ ivpu_err(vdev, "Failed to map BO in IOMMU: %ld\n", PTR_ERR(sgt)); ++ else ++ bo->base.sgt = sgt; ++ } ++ ++ ivpu_bo_unlock(bo); ++ ++ return sgt; ++} ++ + /* +- * ivpu_bo_pin() - pin the backing physical pages and map them to VPU. ++ * ivpu_bo_bind() - pin the backing physical pages and map them to VPU. + * + * This function pins physical memory pages, then maps the physical pages + * to IOMMU address space and finally updates the VPU MMU page tables + * to allow the VPU to translate VPU address to IOMMU address. + */ +-int __must_check ivpu_bo_pin(struct ivpu_bo *bo) ++int __must_check ivpu_bo_bind(struct ivpu_bo *bo) + { + struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); + struct sg_table *sgt; + int ret = 0; + +- ivpu_dbg_bo(vdev, bo, "pin"); ++ ivpu_dbg_bo(vdev, bo, "bind"); + +- sgt = drm_gem_shmem_get_pages_sgt(&bo->base); ++ if (bo->base.base.import_attach) ++ sgt = ivpu_bo_map_attachment(vdev, bo); ++ else ++ sgt = drm_gem_shmem_get_pages_sgt(&bo->base); + if (IS_ERR(sgt)) { + ret = PTR_ERR(sgt); + ivpu_err(vdev, "Failed to map BO in IOMMU: %d\n", ret); +@@ -99,7 +123,9 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, + ret = ivpu_mmu_context_insert_node(ctx, range, ivpu_bo_size(bo), &bo->mm_node); + if (!ret) { + bo->ctx = ctx; ++ bo->ctx_id = ctx->id; + bo->vpu_addr = bo->mm_node.start; ++ ivpu_dbg_bo(vdev, bo, "vaddr"); + } else { + ivpu_err(vdev, "Failed to add BO to context %u: %d\n", ctx->id, ret); + } +@@ -115,7 +141,7 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + { + struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); + +- lockdep_assert(dma_resv_held(bo->base.base.resv) || !kref_read(&bo->base.base.refcount)); ++ dma_resv_assert_held(bo->base.base.resv); + + if (bo->mmu_mapped) { + drm_WARN_ON(&vdev->drm, !bo->ctx); +@@ -134,9 +160,14 @@ static void ivpu_bo_unbind_locked(struct ivpu_bo *bo) + return; + + if (bo->base.sgt) { +- dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); +- sg_free_table(bo->base.sgt); +- kfree(bo->base.sgt); ++ if (bo->base.base.import_attach) { ++ dma_buf_unmap_attachment(bo->base.base.import_attach, ++ bo->base.sgt, DMA_BIDIRECTIONAL); ++ } else { ++ dma_unmap_sgtable(vdev->drm.dev, bo->base.sgt, DMA_BIDIRECTIONAL, 0); ++ sg_free_table(bo->base.sgt); ++ kfree(bo->base.sgt); ++ } + bo->base.sgt = NULL; + } + } +@@ -162,6 +193,7 @@ void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_m + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size) + { ++ struct ivpu_device *vdev = to_ivpu_device(dev); + struct ivpu_bo *bo; + + if (size == 0 || !PAGE_ALIGNED(size)) +@@ -176,6 +208,11 @@ struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t siz + + INIT_LIST_HEAD(&bo->bo_list_node); + ++ mutex_lock(&vdev->bo_list_lock); ++ list_add_tail(&bo->bo_list_node, &vdev->bo_list); ++ mutex_unlock(&vdev->bo_list_lock); ++ ++ ivpu_dbg(vdev, BO, " alloc: bo %8p size %9zu\n", bo, size); + return &bo->base.base; + } + +@@ -184,7 +221,6 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + { + struct device *attach_dev = dev->dev; + struct dma_buf_attachment *attach; +- struct sg_table *sgt; + struct drm_gem_object *obj; + int ret; + +@@ -194,16 +230,10 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + + get_dma_buf(dma_buf); + +- sgt = dma_buf_map_attachment_unlocked(attach, DMA_BIDIRECTIONAL); +- if (IS_ERR(sgt)) { +- ret = PTR_ERR(sgt); +- goto fail_detach; +- } +- +- obj = drm_gem_shmem_prime_import_sg_table(dev, attach, sgt); ++ obj = drm_gem_shmem_prime_import_sg_table(dev, attach, NULL); + if (IS_ERR(obj)) { + ret = PTR_ERR(obj); +- goto fail_unmap; ++ goto fail_detach; + } + + obj->import_attach = attach; +@@ -211,8 +241,6 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + + return obj; + +-fail_unmap: +- dma_buf_unmap_attachment_unlocked(attach, sgt, DMA_BIDIRECTIONAL); + fail_detach: + dma_buf_detach(dma_buf, attach); + dma_buf_put(dma_buf); +@@ -220,7 +248,7 @@ struct drm_gem_object *ivpu_gem_prime_import(struct drm_device *dev, + return ERR_PTR(ret); + } + +-static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags, u32 ctx_id) ++static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 flags) + { + struct drm_gem_shmem_object *shmem; + struct ivpu_bo *bo; +@@ -238,16 +266,9 @@ static struct ivpu_bo *ivpu_bo_alloc(struct ivpu_device *vdev, u64 size, u32 fla + return ERR_CAST(shmem); + + bo = to_ivpu_bo(&shmem->base); +- bo->ctx_id = ctx_id; + bo->base.map_wc = flags & DRM_IVPU_BO_WC; + bo->flags = flags; + +- mutex_lock(&vdev->bo_list_lock); +- list_add_tail(&bo->bo_list_node, &vdev->bo_list); +- mutex_unlock(&vdev->bo_list_lock); +- +- ivpu_dbg_bo(vdev, bo, "alloc"); +- + return bo; + } + +@@ -281,6 +302,8 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + + ivpu_dbg_bo(vdev, bo, "free"); + ++ drm_WARN_ON(&vdev->drm, list_empty(&bo->bo_list_node)); ++ + mutex_lock(&vdev->bo_list_lock); + list_del(&bo->bo_list_node); + mutex_unlock(&vdev->bo_list_lock); +@@ -290,7 +313,10 @@ static void ivpu_gem_bo_free(struct drm_gem_object *obj) + drm_WARN_ON(&vdev->drm, ivpu_bo_size(bo) == 0); + drm_WARN_ON(&vdev->drm, bo->base.vaddr); + ++ ivpu_bo_lock(bo); + ivpu_bo_unbind_locked(bo); ++ ivpu_bo_unlock(bo); ++ + drm_WARN_ON(&vdev->drm, bo->mmu_mapped); + drm_WARN_ON(&vdev->drm, bo->ctx); + +@@ -326,7 +352,7 @@ int ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fi + if (size == 0) + return -EINVAL; + +- bo = ivpu_bo_alloc(vdev, size, args->flags, file_priv->ctx.id); ++ bo = ivpu_bo_alloc(vdev, size, args->flags); + if (IS_ERR(bo)) { + ivpu_err(vdev, "Failed to allocate BO: %pe (ctx %u size %llu flags 0x%x)", + bo, file_priv->ctx.id, args->size, args->flags); +@@ -360,7 +386,7 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, + drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(range->end)); + drm_WARN_ON(&vdev->drm, !PAGE_ALIGNED(size)); + +- bo = ivpu_bo_alloc(vdev, size, flags, IVPU_GLOBAL_CONTEXT_MMU_SSID); ++ bo = ivpu_bo_alloc(vdev, size, flags); + if (IS_ERR(bo)) { + ivpu_err(vdev, "Failed to allocate BO: %pe (vpu_addr 0x%llx size %llu flags 0x%x)", + bo, range->start, size, flags); +@@ -371,7 +397,7 @@ ivpu_bo_create(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx, + if (ret) + goto err_put; + +- ret = ivpu_bo_pin(bo); ++ ret = ivpu_bo_bind(bo); + if (ret) + goto err_put; + +diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h +index aa8ff14f7aae1..ade0d127453ff 100644 +--- a/drivers/accel/ivpu/ivpu_gem.h ++++ b/drivers/accel/ivpu/ivpu_gem.h +@@ -24,7 +24,7 @@ struct ivpu_bo { + bool mmu_mapped; + }; + +-int ivpu_bo_pin(struct ivpu_bo *bo); ++int ivpu_bo_bind(struct ivpu_bo *bo); + void ivpu_bo_unbind_all_bos_from_context(struct ivpu_device *vdev, struct ivpu_mmu_context *ctx); + + struct drm_gem_object *ivpu_gem_create_object(struct drm_device *dev, size_t size); +diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c +index dbefa43c74e28..1e4caf5726474 100644 +--- a/drivers/accel/ivpu/ivpu_job.c ++++ b/drivers/accel/ivpu/ivpu_job.c +@@ -732,7 +732,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 + + job->bos[i] = to_ivpu_bo(obj); + +- ret = ivpu_bo_pin(job->bos[i]); ++ ret = ivpu_bo_bind(job->bos[i]); + if (ret) + return ret; + } +-- +2.51.0 + diff --git a/queue-6.18/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-6.18/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..eaaaba33a3 --- /dev/null +++ b/queue-6.18/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From cb005a68e2a8c5d59435ddbc73695f2f81a6fdb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 9b6b71a2ffb54..a4498357bd165 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-6.18/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-6.18/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..90780ac497 --- /dev/null +++ b/queue-6.18/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From accce5e649eb636ea9ca98fd6b23efdf82ce006a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index 43d5e457814e1..b12057baaae7b 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1714,6 +1714,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch b/queue-6.18/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch new file mode 100644 index 0000000000..dd833f2981 --- /dev/null +++ b/queue-6.18/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch @@ -0,0 +1,41 @@ +From 63a6cf0c84aae38bb0dc5e30858d985441f7a8cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:38:51 +0200 +Subject: ARM: dts: am335x-netcom-plus-2xx: add missing GPIO labels + +From: Yegor Yefremov + +[ Upstream commit d0c4b1723c419a18cb434903c7754954ecb51d35 ] + +Fixes: 8e9d75fd2ec2 ("ARM: dts: am335x-netcom: add GPIO names for NetCom Plus 2-port devices") + +Signed-off-by: Yegor Yefremov +Link: https://lore.kernel.org/r/20251007103851.3765678-1-yegorslists@googlemail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +index f66d57bb685ee..f0519ab301416 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +@@ -222,10 +222,10 @@ &gpio3 { + "ModeA1", + "ModeA2", + "ModeA3", +- "NC", +- "NC", +- "NC", +- "NC", ++ "ModeB0", ++ "ModeB1", ++ "ModeB2", ++ "ModeB3", + "NC", + "NC", + "NC", +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-am33xx-add-missing-serial-console-speed.patch b/queue-6.18/arm-dts-am33xx-add-missing-serial-console-speed.patch new file mode 100644 index 0000000000..571ec879bd --- /dev/null +++ b/queue-6.18/arm-dts-am33xx-add-missing-serial-console-speed.patch @@ -0,0 +1,213 @@ +From c8002ffefc97f93d7ac92d178f71d9cdb70b85cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:05 +0200 +Subject: ARM: dts: am33xx: Add missing serial console speed + +From: Geert Uytterhoeven + +[ Upstream commit 9c95fc710b0d05f797db9e26d56524efa74f8978 ] + +Without a serial console speed specified in chosen/stdout-path in the +DTB, the serial console uses the default speed of the serial driver, +unless explicitly overridden in a legacy console= kernel command-line +parameter. + +After dropping "ti,omap3-uart" from the list of compatible values in DT, +AM33xx serial ports can no longer be used with the legacy OMAP serial +driver, but only with the OMAP-flavored 8250 serial driver (which is +mutually-exclusive with the former). However, replacing +CONFIG_SERIAL_OMAP=y by CONFIG_SERIAL_8250_OMAP=y (with/without enabling +CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP) may not be sufficient to restore +serial console functionality: the legacy OMAP serial driver defaults to +115200 bps, while the 8250 serial driver defaults to 9600 bps, causing +no visible output on the serial console when no appropriate console= +kernel command-line parameter is specified. + +Fix this for all AM33xx boards by adding ":115200n8" to +chosen/stdout-path. This requires replacing the "&uartN" reference by +the corresponding "serialN" DT alias. + +Fixes: ca8be8fc2c306efb ("ARM: dts: am33xx-l4: fix UART compatible") +Fixes: 077e1cde78c3f904 ("ARM: omap2plus_defconfig: Enable 8250_OMAP") +Closes: https://lore.kernel.org/CAMuHMdUb7Jb2=GqK3=Rn+Gv5G9KogcQieqDvjDCkJA4zyX4VcA@mail.gmail.com +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Matti Vaittinen +Tested-by: Matti Vaittinen +Reviewed-by: Bruno Thomsen +Link: https://lore.kernel.org/r/63cef5c3643d359e8ec13366ca79377f12dd73b1.1759398641.git.geert+renesas@glider.be +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi | 2 +- + arch/arm/boot/dts/ti/omap/am335x-boneblue.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-evm.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-evmsk.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-guardian.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-icev2.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-pdu001.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts | 2 +- + arch/arm/boot/dts/ti/omap/am335x-sl50.dts | 2 +- + 12 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi +index ad1e60a9b6fde..b75dabfa56ae7 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/ti/omap/am335x-bone-common.dtsi +@@ -16,7 +16,7 @@ memory@80000000 { + }; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts +index f579df4c2c540..d430f0bef1653 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-boneblue.dts +@@ -13,7 +13,7 @@ / { + compatible = "ti,am335x-bone-blue", "ti,am33xx"; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts b/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts +index 648e97fe1dfd5..ae5bc58984972 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-chiliboard.dts +@@ -12,7 +12,7 @@ / { + "ti,am33xx"; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-evm.dts b/arch/arm/boot/dts/ti/omap/am335x-evm.dts +index 20222f82f21bf..856fa1191ed24 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-evm.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-evm.dts +@@ -23,7 +23,7 @@ memory@80000000 { + }; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + vbat: fixedregulator0 { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts +index eba888dcd60e7..d8baccdf8bc46 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-evmsk.dts +@@ -30,7 +30,7 @@ memory@80000000 { + }; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + vbat: fixedregulator0 { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts +index 4b070e634b281..6ce3a2d029eed 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-guardian.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-guardian.dts +@@ -14,7 +14,7 @@ / { + compatible = "bosch,am335x-guardian", "ti,am33xx"; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + tick-timer = &timer2; + }; + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts +index 6f0f4fba043b9..ba488bba6925d 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-icev2.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-icev2.dts +@@ -22,7 +22,7 @@ memory@80000000 { + }; + + chosen { +- stdout-path = &uart3; ++ stdout-path = "serial3:115200n8"; + }; + + vbat: fixedregulator0 { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts +index 06a352f98b220..476a6bdaf43f3 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-myirtech-myd.dts +@@ -15,7 +15,7 @@ / { + compatible = "myir,myd-am335x", "myir,myc-am335x", "ti,am33xx"; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + clk12m: clk12m { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts +index d28d397288476..23caaaabf3513 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-osd3358-sm-red.dts +@@ -147,7 +147,7 @@ simple-audio-card,codec { + }; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts +index c9ccb9de21ad7..9f611debc2090 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-pdu001.dts +@@ -21,7 +21,7 @@ / { + compatible = "ti,am33xx"; + + chosen { +- stdout-path = &uart3; ++ stdout-path = "serial3:115200n8"; + }; + + cpus { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts +index 78ce860e59b3d..24d9f90fad01f 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-pocketbeagle.dts +@@ -15,7 +15,7 @@ / { + compatible = "ti,am335x-pocketbeagle", "ti,am335x-bone", "ti,am33xx"; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +diff --git a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts +index f3524e5ee43e2..1dc4e344efd63 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-sl50.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-sl50.dts +@@ -25,7 +25,7 @@ memory@80000000 { + }; + + chosen { +- stdout-path = &uart0; ++ stdout-path = "serial0:115200n8"; + }; + + leds { +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch b/queue-6.18/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch new file mode 100644 index 0000000000..e486f10a97 --- /dev/null +++ b/queue-6.18/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch @@ -0,0 +1,43 @@ +From 63e994fe47d6a791bd3e1a8d126cbab11709ca16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:15 +0200 +Subject: ARM: dts: omap3: beagle-xm: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit f7f3bc18300a230e0f1bfb17fc8889435c1e47f5 ] + +The "ti,twl4030-power-beagleboard-xm" compatible string is obsolete and +is not supported by any in-kernel driver. Currently, the kernel falls +back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a +driver to this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: 9188883fd66e9 ("ARM: dts: Enable twl4030 off-idle configuration for selected omaps") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-3-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +index 08ee0f8ea68fd..71b39a923d37c 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +@@ -291,7 +291,7 @@ codec { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch b/queue-6.18/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch new file mode 100644 index 0000000000..b9be07d113 --- /dev/null +++ b/queue-6.18/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch @@ -0,0 +1,43 @@ +From a2abf93f1755deea5ec5bed7bb784fffa953a3ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:16 +0200 +Subject: ARM: dts: omap3: n900: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit 3862123e9b56663c7a3e4a308e6e65bffe44f646 ] + +The "ti,twl4030-power-n900" compatible string is obsolete and is not +supported by any in-kernel driver. Currently, the kernel falls back to +the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to +this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: daebabd578647 ("mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-4-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-n900.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +index c50ca572d1b9b..7db73d9bed9e4 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +@@ -508,7 +508,7 @@ twl_audio: audio { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-renesas-gose-remove-superfluous-port-propert.patch b/queue-6.18/arm-dts-renesas-gose-remove-superfluous-port-propert.patch new file mode 100644 index 0000000000..6bc37a52e7 --- /dev/null +++ b/queue-6.18/arm-dts-renesas-gose-remove-superfluous-port-propert.patch @@ -0,0 +1,39 @@ +From d25436b2ac79f0021468346c85287cdbdcde187a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 11:36:02 +0200 +Subject: ARM: dts: renesas: gose: Remove superfluous port property + +From: Wolfram Sang + +[ Upstream commit 00df14f34615630f92f97c9d6790bd9d25c4242d ] + +'bus-width' is defined for the corresponding vin input port already. +No need to declare it in the output port again. Fixes: + + arch/arm/boot/dts/renesas/r8a7793-gose.dtb: composite-in@20 (adi,adv7180cp): ports:port@3:endpoint: Unevaluated properties are not allowed ('bus-width' was unexpected) + from schema $id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml# + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250929093616.17679-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r8a7793-gose.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +index 45b267ec26794..5c6928c941aca 100644 +--- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts ++++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +@@ -373,7 +373,6 @@ adv7180_in: endpoint { + port@3 { + reg = <3>; + adv7180_out: endpoint { +- bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch b/queue-6.18/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch new file mode 100644 index 0000000000..34fa5c72e8 --- /dev/null +++ b/queue-6.18/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch @@ -0,0 +1,41 @@ +From b419ee423ccde63e4bce610a4508cb893806cc79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:46:25 +0200 +Subject: ARM: dts: renesas: r9a06g032-rzn1d400-db: Drop invalid #cells + properties + +From: Wolfram Sang + +[ Upstream commit ca7fffb6e92a7c93604ea2bae0e1c89b20750937 ] + +The 'ethernet-ports' node in the SoC DTSI handles them already. Fixes: + + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dtb: switch@44050000 (renesas,r9a06g032-a5psw): Unevaluated properties are not allowed ('#address-cells', '#size-cells' were unexpected) + from schema $id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# + +Fixes: 5b6d7c3c5861ad4a ("ARM: dts: r9a06g032-rzn1d400-db: Add switch description") +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251007104624.19786-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +index 3258b2e274346..4a72aa7663f25 100644 +--- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts ++++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +@@ -308,8 +308,6 @@ &rtc0 { + + &switch { + status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch b/queue-6.18/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..73be8f6dab --- /dev/null +++ b/queue-6.18/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From b3cde0ad7448ea72f0d28a1f6f68b8fa911d6243 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:16 +0100 +Subject: ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-3-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +index df229fb8a16be..8a635bee59fa9 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +@@ -853,6 +853,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&vtf_reg>; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch b/queue-6.18/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..42ca68a6cb --- /dev/null +++ b/queue-6.18/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From dafe84bd3574dde09cc82c929c12c5382814e105 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:17 +0100 +Subject: ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97cc9c346b2c9cde075b9420fc172137d2427711 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: a19f6efc01df ("ARM: dts: exynos: Enable WLAN support for the Trats board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-4-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +index 95e0e01b6ff6b..6bd902cb8f4ad 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +@@ -518,6 +518,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&tflash_reg>; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch b/queue-6.18/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..f0971d8b9f --- /dev/null +++ b/queue-6.18/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From e2abfff8c2d454cdc834a5f2e693aa7dd2c913f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:18 +0100 +Subject: ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f77cbb9a3e5d ("ARM: dts: exynos: Add bcm4334 device node to Trats2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-5-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +index 05ddddb565ee3..48245b1665a69 100644 +--- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +@@ -1440,6 +1440,7 @@ &sdhci_3 { + #address-cells = <1>; + #size-cells = <0>; + non-removable; ++ cap-power-off-card; + bus-width = <4>; + + mmc-pwrseq = <&wlan_pwrseq>; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch b/queue-6.18/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch new file mode 100644 index 0000000000..daa2f06998 --- /dev/null +++ b/queue-6.18/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch @@ -0,0 +1,43 @@ +From c645f504505450aa65ba51af75778d3532d452de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:15 +0100 +Subject: ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97aee67e2406ea381408915e606c5f86448f3949 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f1b0ffaa686f ("ARM: dts: exynos: Enable WLAN support for the UniversalC210 board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-2-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +index bdc30f8cf748f..91490693432b6 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +@@ -610,6 +610,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&ldo5_reg>; +-- +2.51.0 + diff --git a/queue-6.18/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch b/queue-6.18/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch new file mode 100644 index 0000000000..6ea28ae664 --- /dev/null +++ b/queue-6.18/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch @@ -0,0 +1,50 @@ +From 2d8fc28440dd51f2ed51d63a23042d2ade7ca573 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 00:46:11 +0200 +Subject: ARM: dts: stm32: stm32mp157c-phycore: Fix STMPE811 touchscreen node + properties + +From: Jihed Chaibi + +[ Upstream commit e40b061cd379f4897e705d17cf1b4572ad0f3963 ] + +Move st,adc-freq, st,mod-12b, st,ref-sel, and st,sample-time properties +from the touchscreen subnode to the parent touch@44 node. These properties +are defined in the st,stmpe.yaml schema for the parent node, not the +touchscreen subnode, resolving the validation error about unevaluated +properties. + +Fixes: 27538a18a4fcc ("ARM: dts: stm32: add STM32MP1-based Phytec SoM") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250915224611.169980-1-jihed.chaibi.dev@gmail.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + .../boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +index bf0c32027baf7..370b2afbf15bf 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +@@ -185,13 +185,13 @@ touch@44 { + interrupt-parent = <&gpioi>; + vio-supply = <&v3v3>; + vcc-supply = <&v3v3>; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <1>; + + touchscreen { + compatible = "st,stmpe-ts"; +- st,sample-time = <4>; +- st,mod-12b = <1>; +- st,ref-sel = <0>; +- st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-amlogic-meson-g12b-fix-l2-cache-reference-.patch b/queue-6.18/arm64-dts-amlogic-meson-g12b-fix-l2-cache-reference-.patch new file mode 100644 index 0000000000..03303dfc04 --- /dev/null +++ b/queue-6.18/arm64-dts-amlogic-meson-g12b-fix-l2-cache-reference-.patch @@ -0,0 +1,51 @@ +From e9c7e80933360b35f0ae1a06226a1f4108200888 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 23 Nov 2025 18:14:10 +0100 +Subject: arm64: dts: amlogic: meson-g12b: Fix L2 cache reference for S922X + CPUs + +From: Guillaume La Roque + +[ Upstream commit a7ab6f946683e065fa22db1cc2f2748d4584178a ] + +The original addition of cache information for the Amlogic S922X SoC +used the wrong next-level cache node for CPU cores 100 and 101, +incorrectly referencing `l2_cache_l`. These cores actually belong to +the big cluster and should reference `l2_cache_b`. Update the device +tree accordingly. + +Fixes: e7f85e6c155a ("arm64: dts: amlogic: Add cache information to the Amlogic S922X SoC") +Signed-off-by: Guillaume La Roque +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251123-fixkhadas-v1-1-045348f0a4c2@baylibre.com +Signed-off-by: Neil Armstrong +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +index f04efa8282561..23358d94844c9 100644 +--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi ++++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi +@@ -87,7 +87,7 @@ cpu100: cpu@100 { + i-cache-line-size = <32>; + i-cache-size = <0x8000>; + i-cache-sets = <32>; +- next-level-cache = <&l2_cache_l>; ++ next-level-cache = <&l2_cache_b>; + #cooling-cells = <2>; + }; + +@@ -103,7 +103,7 @@ cpu101: cpu@101 { + i-cache-line-size = <32>; + i-cache-size = <0x8000>; + i-cache-sets = <32>; +- next-level-cache = <&l2_cache_l>; ++ next-level-cache = <&l2_cache_b>; + #cooling-cells = <2>; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-exynos-gs101-fix-clock-module-unit-reg-siz.patch b/queue-6.18/arm64-dts-exynos-gs101-fix-clock-module-unit-reg-siz.patch new file mode 100644 index 0000000000..ee6d8cf2b2 --- /dev/null +++ b/queue-6.18/arm64-dts-exynos-gs101-fix-clock-module-unit-reg-siz.patch @@ -0,0 +1,101 @@ +From 158aac9174fff1aa401372f82c6664d2e53fb502 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 21:51:33 +0100 +Subject: arm64: dts: exynos: gs101: fix clock module unit reg sizes +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Griffin + +[ Upstream commit ddb2a16804d005a96e8b5ffc0925e2f5bff65767 ] + +The memory map lists each clock module unit as having a size of +0x10000. Additionally there are some undocumented registers in this region +that need to be used for automatic clock gating mode. Some of those +registers also need to be saved/restored on suspend & resume. + +Fixes: 86124c76683e ("arm64: dts: exynos: gs101: enable cmu-hsi2 clock controller") +Fixes: 4982a4a2092e ("arm64: dts: exynos: gs101: enable cmu-hsi0 clock controller") +Fixes: 7d66d98b5bf3 ("arm64: dts: exynos: gs101: enable cmu-peric1 clock controller") +Fixes: e62c706f3aa0 ("arm64: dts: exynos: gs101: enable cmu-peric0 clock controller") +Fixes: ea89fdf24fd9 ("arm64: dts: exynos: google: Add initial Google gs101 SoC support") +Signed-off-by: Peter Griffin +Reviewed-by: André Draszik +Link: https://patch.msgid.link/20251013-automatic-clocks-v1-4-72851ee00300@linaro.org +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/exynos/google/gs101.dtsi | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +index 31c99526470d0..6335e0a8136be 100644 +--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi ++++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +@@ -288,7 +288,7 @@ soc: soc@0 { + + cmu_misc: clock-controller@10010000 { + compatible = "google,gs101-cmu-misc"; +- reg = <0x10010000 0x8000>; ++ reg = <0x10010000 0x10000>; + #clock-cells = <1>; + clocks = <&cmu_top CLK_DOUT_CMU_MISC_BUS>, + <&cmu_top CLK_DOUT_CMU_MISC_SSS>; +@@ -365,7 +365,7 @@ ppi_cluster2: interrupt-partition-2 { + + cmu_peric0: clock-controller@10800000 { + compatible = "google,gs101-cmu-peric0"; +- reg = <0x10800000 0x4000>; ++ reg = <0x10800000 0x10000>; + #clock-cells = <1>; + clocks = <&ext_24_5m>, + <&cmu_top CLK_DOUT_CMU_PERIC0_BUS>, +@@ -911,7 +911,7 @@ spi_14: spi@10a20000 { + + cmu_peric1: clock-controller@10c00000 { + compatible = "google,gs101-cmu-peric1"; +- reg = <0x10c00000 0x4000>; ++ reg = <0x10c00000 0x10000>; + #clock-cells = <1>; + clocks = <&ext_24_5m>, + <&cmu_top CLK_DOUT_CMU_PERIC1_BUS>, +@@ -1265,7 +1265,7 @@ spi_13: spi@10d60000 { + + cmu_hsi0: clock-controller@11000000 { + compatible = "google,gs101-cmu-hsi0"; +- reg = <0x11000000 0x4000>; ++ reg = <0x11000000 0x10000>; + #clock-cells = <1>; + + clocks = <&ext_24_5m>, +@@ -1332,7 +1332,7 @@ pinctrl_hsi1: pinctrl@11840000 { + + cmu_hsi2: clock-controller@14400000 { + compatible = "google,gs101-cmu-hsi2"; +- reg = <0x14400000 0x4000>; ++ reg = <0x14400000 0x10000>; + #clock-cells = <1>; + clocks = <&ext_24_5m>, + <&cmu_top CLK_DOUT_CMU_HSI2_BUS>, +@@ -1395,7 +1395,7 @@ ufs_0_phy: phy@14704000 { + + cmu_apm: clock-controller@17400000 { + compatible = "google,gs101-cmu-apm"; +- reg = <0x17400000 0x8000>; ++ reg = <0x17400000 0x10000>; + #clock-cells = <1>; + + clocks = <&ext_24_5m>; +@@ -1497,7 +1497,7 @@ pinctrl_gsacore: pinctrl@17a80000 { + + cmu_top: clock-controller@1e080000 { + compatible = "google,gs101-cmu-top"; +- reg = <0x1e080000 0x8000>; ++ reg = <0x1e080000 0x10000>; + #clock-cells = <1>; + + clocks = <&ext_24_5m>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch b/queue-6.18/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch new file mode 100644 index 0000000000..750cdb9513 --- /dev/null +++ b/queue-6.18/arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch @@ -0,0 +1,45 @@ +From 7ad4e1e443279c4bacfd86e5b0e8809107a70d3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 21:51:34 +0100 +Subject: arm64: dts: exynos: gs101: fix sysreg_apm reg property +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Peter Griffin + +[ Upstream commit 4348c22a4f15dbef1314f1a353d7f053b24e9ace ] + +Both the start address and size are incorrect for the apm_sysreg DT +node. Update to match the TRM (rather than how it was defined +downstream). + +Fixes: ea89fdf24fd9 ("arm64: dts: exynos: google: Add initial Google gs101 SoC support") +Signed-off-by: Peter Griffin +Reviewed-by: André Draszik +Link: https://patch.msgid.link/20251013-automatic-clocks-v1-5-72851ee00300@linaro.org +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/exynos/google/gs101.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +index 6335e0a8136be..c01ff4e1b0d5d 100644 +--- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi ++++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi +@@ -1402,9 +1402,9 @@ cmu_apm: clock-controller@17400000 { + clock-names = "oscclk"; + }; + +- sysreg_apm: syscon@174204e0 { ++ sysreg_apm: syscon@17420000 { + compatible = "google,gs101-apm-sysreg", "syscon"; +- reg = <0x174204e0 0x1000>; ++ reg = <0x17420000 0x10000>; + }; + + pmu_system_controller: system-controller@17460000 { +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch b/queue-6.18/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch new file mode 100644 index 0000000000..1c8a6a8469 --- /dev/null +++ b/queue-6.18/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch @@ -0,0 +1,38 @@ +From df13d8266103cf48380620550cb7b6368a1f10a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:45 -0700 +Subject: arm64: dts: freescale: imx8mp-venice-gw7905-2x: remove duplicate + usdhc1 props + +From: Tim Harvey + +[ Upstream commit 8b7e58ab4a02601a0e86e9f9701d4612038d8b29 ] + +Remove the un-intended duplicate properties from usdhc1. + +Fixes: 0d5b288c2110e ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index cbf0c9a740faa..303995a8adce8 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -423,9 +423,6 @@ &usdhc1 { + bus-width = <4>; + non-removable; + status = "okay"; +- bus-width = <4>; +- non-removable; +- status = "okay"; + }; + + /* eMMC */ +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-6.18/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..5e4d414cb0 --- /dev/null +++ b/queue-6.18/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From a1007d931aa68b74267a62dd186d6ce5abfa68d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 752caa38eb03b..266038fbbef97 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -351,17 +351,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch b/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch new file mode 100644 index 0000000000..65214f5917 --- /dev/null +++ b/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch @@ -0,0 +1,87 @@ +From e6c5655683505d880a33cc5678ccec49ad805a30 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:51 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board sdhc1 + +From: Tim Harvey + +[ Upstream commit 9db04b310ef99b546e4240c55842e81b06b78579 ] + +SDHC1 on the GW702x SOM routes to a connector for use on a baseboard +and as such are defined in the baseboard device-trees. + +Remove it from the gw702x SOM device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 20 ------------------- + .../dts/freescale/imx8mp-venice-gw72xx.dtsi | 11 ---------- + 2 files changed, 31 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 086ee4510cd83..fb159199b39de 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -402,15 +402,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board */ +-&usdhc1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_usdhc1>; +- bus-width = <4>; +- non-removable; +- status = "okay"; +-}; +- + /* eMMC */ + &usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; +@@ -513,17 +504,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +index cf747ec6fa16e..76020ef89bf3e 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +@@ -365,17 +365,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch b/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch new file mode 100644 index 0000000000..dcea2ee602 --- /dev/null +++ b/queue-6.18/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch @@ -0,0 +1,85 @@ +From b9d1b262cc9f1c397757ca153057b4dac040155d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:50 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board uart + +From: Tim Harvey + +[ Upstream commit effe98060f70eb96e142f656e750d6af275ceac3 ] + +UART1 and UART3 go to a connector for use on a baseboard and as such are +defined in the baseboard device-trees. Remove them from the gw702x SOM +device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 28 ------------------- + 1 file changed, 28 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 303995a8adce8..086ee4510cd83 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -395,13 +395,6 @@ &i2c3 { + status = "okay"; + }; + +-/* off-board header */ +-&uart1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart1>; +- status = "okay"; +-}; +- + /* console */ + &uart2 { + pinctrl-names = "default"; +@@ -409,13 +402,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board header */ +-&uart3 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart3>; +- status = "okay"; +-}; +- + /* off-board */ + &usdhc1 { + pinctrl-names = "default"; +@@ -520,13 +506,6 @@ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2 + >; + }; + +- pinctrl_uart1: uart1grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 +- MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 +- >; +- }; +- + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 +@@ -534,13 +513,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_uart3: uart3grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 +- MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 +- >; +- }; +- + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch b/queue-6.18/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch new file mode 100644 index 0000000000..405e4febb1 --- /dev/null +++ b/queue-6.18/arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch @@ -0,0 +1,35 @@ +From d2d132be94b6b080e53f0ad897a912df99e82034 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 10:27:04 +0800 +Subject: arm64: dts: imx95-15x15-evk: add fan-supply property for pwm-fan + +From: Joy Zou + +[ Upstream commit 93b2fac5cdaf0d501d04c9a4b0e5024632a6af7c ] + +Add fan-supply regulator to pwm-fan node to specify power source. + +Fixes: e3e8b199aff8 ("arm64: dts: imx95: Add imx95-15x15-evk support") +Signed-off-by: Joy Zou +Reviewed-by: Frank Li +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +index 148243470dd4a..0953c25ef5576 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts ++++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +@@ -61,6 +61,7 @@ chosen { + + fan0: pwm-fan { + compatible = "pwm-fan"; ++ fan-supply = <®_vcc_12v>; + #cooling-cells = <2>; + cooling-levels = <64 128 192 255>; + pwms = <&tpm6 0 4000000 PWM_POLARITY_INVERTED>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch b/queue-6.18/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch new file mode 100644 index 0000000000..05b86718f7 --- /dev/null +++ b/queue-6.18/arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch @@ -0,0 +1,36 @@ +From bcc38f096d78172292dd34b515c51fa946a5d784 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 13:49:08 +0100 +Subject: arm64: dts: imx95-tqma9596sa: fix TPM5 pinctrl node name + +From: Markus Niebel + +[ Upstream commit 046cb64923e8c05a8fb656baffcd8c3fc67fb688 ] + +tpm4grp will be overwritten. Fix node name + +Fixes: 91d1ff322c47 ("arm64: dt: imx95: Add TQMa95xxSA") +Signed-off-by: Markus Niebel +Signed-off-by: Alexander Stein +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +index 180124cc5bce1..c3bb61ea67961 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +@@ -617,7 +617,7 @@ pinctrl_tpm4: tpm4grp { + fsl,pins = ; + }; + +- pinctrl_tpm5: tpm4grp { ++ pinctrl_tpm5: tpm5grp { + fsl,pins = ; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch b/queue-6.18/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch new file mode 100644 index 0000000000..bfd3f66b89 --- /dev/null +++ b/queue-6.18/arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch @@ -0,0 +1,37 @@ +From 090a776acf32f5c03fb784855bbd17ecb0edd404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 13:49:09 +0100 +Subject: arm64: dts: imx95-tqma9596sa: reduce maximum FlexSPI frequency to + 66MHz + +From: Alexander Stein + +[ Upstream commit 461be3802562b2d41250b40868310579a32f32c1 ] + +66 MHz is the maximum FlexPI clock frequency in normal/overdrive mode +when RXCLKSRC = 0 (Default) + +Fixes: 91d1ff322c47 ("arm64: dt: imx95: Add TQMa95xxSA") +Signed-off-by: Alexander Stein +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +index c3bb61ea67961..16c40d11d3b5d 100644 +--- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +@@ -115,7 +115,7 @@ &flexspi1 { + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; +- spi-max-frequency = <80000000>; ++ spi-max-frequency = <66000000>; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + vcc-supply = <®_1v8>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-mediatek-mt8195-fix-address-range-for-jpeg.patch b/queue-6.18/arm64-dts-mediatek-mt8195-fix-address-range-for-jpeg.patch new file mode 100644 index 0000000000..4d9df871b5 --- /dev/null +++ b/queue-6.18/arm64-dts-mediatek-mt8195-fix-address-range-for-jpeg.patch @@ -0,0 +1,50 @@ +From 8e5bae7690ceee4c3de0ff771092308b0633ed1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 18:00:42 +0800 +Subject: arm64: dts: mediatek: mt8195: Fix address range for JPEG decoder core + 1 + +From: Chen-Yu Tsai + +[ Upstream commit ce48af13e6381772cc27676be63a6d9176c14a49 ] + +The base address of JPEG decoder core 1 should start at 0x10000, and +have a size of 0x10000, i.e. it is right after core 0. + +Instead the core has the same base address as core 0, and with a crazy +large size. This looks like a mixup of address and size cells when the +ranges were converted. + +This causes the kernel to fail to register the second core due to sysfs +name conflicts: + + sysfs: cannot create duplicate filename '/devices/platform/soc/soc:jpeg-decoder@1a040000/1a040000.jpgdec' + +Fix up the address range. + +Fixes: a9eac43d039f ("arm64: dts: mediatek: mt8195: Fix ranges for jpeg enc/decoder nodes") +Signed-off-by: Chen-Yu Tsai +Acked-by: AngeloGioacchino Del Regno +Link: https://lore.kernel.org/r/20251127100044.612825-1-wenst@chromium.org +Signed-off-by: Arnd Bergmann +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/mediatek/mt8195.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8195.dtsi b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +index ec452d6570314..c7adafaa83288 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8195.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8195.dtsi +@@ -3067,7 +3067,7 @@ jpgdec@0,0 { + + jpgdec@0,10000 { + compatible = "mediatek,mt8195-jpgdec-hw"; +- reg = <0 0 0x10000 0x10000>;/* JPGDEC_C1 */ ++ reg = <0 0x10000 0 0x10000>;/* JPGDEC_C1 */ + iommus = <&iommu_vdo M4U_PORT_L19_JPGDEC_WDMA0>, + <&iommu_vdo M4U_PORT_L19_JPGDEC_BSDMA0>, + <&iommu_vdo M4U_PORT_L19_JPGDEC_WDMA1>, +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-ipq5424-correct-the-tf-a-reserved-mem.patch b/queue-6.18/arm64-dts-qcom-ipq5424-correct-the-tf-a-reserved-mem.patch new file mode 100644 index 0000000000..79fd330e2b --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-ipq5424-correct-the-tf-a-reserved-mem.patch @@ -0,0 +1,37 @@ +From ecf22ff42de560ab1382675b0ff3e124fa1298e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 10:25:01 +0530 +Subject: arm64: dts: qcom: ipq5424: correct the TF-A reserved memory to 512K + +From: Kathiravan Thirumoorthy + +[ Upstream commit 28803705b552a0a711fa849490f14dca2bc5296e ] + +Correct the reserved memory size for TF-A to 512K, as it was mistakenly +marked as 500K. Update the reserved memory node accordingly. + +Fixes: 8517204c982b ("arm64: dts: qcom: ipq5424: Add reserved memory for TF-A") +Signed-off-by: Kathiravan Thirumoorthy +Link: https://lore.kernel.org/r/20251014-tfa-reserved-mem-v1-1-48c82033c8a7@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/ipq5424.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/ipq5424.dtsi b/arch/arm64/boot/dts/qcom/ipq5424.dtsi +index ef2b52f3597d9..227d5ce297515 100644 +--- a/arch/arm64/boot/dts/qcom/ipq5424.dtsi ++++ b/arch/arm64/boot/dts/qcom/ipq5424.dtsi +@@ -213,7 +213,7 @@ smem@8a800000 { + }; + + tfa@8a832000 { +- reg = <0x0 0x8a832000 0x0 0x7d000>; ++ reg = <0x0 0x8a832000 0x0 0x80000>; + no-map; + status = "disabled"; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-lemans-add-missing-quirk-for-hs-only-.patch b/queue-6.18/arm64-dts-qcom-lemans-add-missing-quirk-for-hs-only-.patch new file mode 100644 index 0000000000..88ece72b6a --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-lemans-add-missing-quirk-for-hs-only-.patch @@ -0,0 +1,39 @@ +From de3c6dbc94ee554d650b697fb96d6f03c8064b14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 16:20:19 +0530 +Subject: arm64: dts: qcom: lemans: Add missing quirk for HS only USB + controller + +From: Krishna Kurapati + +[ Upstream commit 0903296efd0b4e17c8d556ce8c33347147301870 ] + +The PIPE clock is provided by the USB3 PHY, which is predictably not +connected to the HS-only controller. Add "qcom,select-utmi-as-pipe-clk" +quirk to HS only USB controller to disable pipe clock requirement. + +Fixes: de1001525c1a ("arm64: dts: qcom: sa8775p: add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20251024105019.2220832-3-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/lemans.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi +index cf685cb186edc..c2d2200d845b3 100644 +--- a/arch/arm64/boot/dts/qcom/lemans.dtsi ++++ b/arch/arm64/boot/dts/qcom/lemans.dtsi +@@ -4106,6 +4106,7 @@ usb_2: usb@a400000 { + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_USB2 0>; + interconnect-names = "usb-ddr", "apps-usb"; + ++ qcom,select-utmi-as-pipe-clk; + wakeup-source; + + iommus = <&apps_smmu 0x020 0x0>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch b/queue-6.18/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch new file mode 100644 index 0000000000..13b8b03c93 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch @@ -0,0 +1,40 @@ +From 4fb699eae45c802f99f1bc0e21c042a4a8ed29a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:01 +0300 +Subject: arm64: dts: qcom: msm8996: add interconnect paths to USB2 controller + +From: Dmitry Baryshkov + +[ Upstream commit 242f7558e7bf54cb63c06506f7b0630dd67d45a4 ] + +Add the missing interconnects to the USB2 host. The Fixes tag points to +the commit which broke probing of the USB host on that platform. + +Fixes: 130733a10079 ("interconnect: qcom: msm8996: Promote to core_initcall") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Acked-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-2-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index c75b522f6eba6..33608b1d7d060 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3496,6 +3496,9 @@ usb2: usb@76f8800 { + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + ++ interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, ++ <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; ++ interconnect-names = "usb-ddr", "apps-usb"; + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch b/queue-6.18/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch new file mode 100644 index 0000000000..d89673a1ce --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch @@ -0,0 +1,60 @@ +From 94dc7fdf08de3b954f286c3acdb028749d05b84d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:54:56 +0200 +Subject: arm64: dts: qcom: qcm2290: Fix camss register prop ordering + +From: Loic Poulain + +[ Upstream commit 67445dc8a8060309eeb7aebbc41fa0e58302fc09 ] + +The qcm2290 CAMSS node has been applied from the V4 series, but a later +version changed the order of the register property, fix it to prevent +dtb check error. + +Fixes: 2b3aef30dd9d ("arm64: dts: qcom: qcm2290: Add CAMSS node") +Signed-off-by: Loic Poulain +Link: https://lore.kernel.org/r/20250918155456.1158691-1-loic.poulain@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm2290.dtsi | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/qcm2290.dtsi b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +index 08141b41de246..3b0ba590ee825 100644 +--- a/arch/arm64/boot/dts/qcom/qcm2290.dtsi ++++ b/arch/arm64/boot/dts/qcom/qcm2290.dtsi +@@ -1685,25 +1685,25 @@ cci_i2c1: i2c-bus@1 { + }; + }; + +- camss: camss@5c6e000 { ++ camss: camss@5c11000 { + compatible = "qcom,qcm2290-camss"; + +- reg = <0x0 0x5c6e000 0x0 0x1000>, ++ reg = <0x0 0x5c11000 0x0 0x1000>, ++ <0x0 0x5c6e000 0x0 0x1000>, + <0x0 0x5c75000 0x0 0x1000>, + <0x0 0x5c52000 0x0 0x1000>, + <0x0 0x5c53000 0x0 0x1000>, + <0x0 0x5c66000 0x0 0x400>, + <0x0 0x5c68000 0x0 0x400>, +- <0x0 0x5c11000 0x0 0x1000>, + <0x0 0x5c6f000 0x0 0x4000>, + <0x0 0x5c76000 0x0 0x4000>; +- reg-names = "csid0", ++ reg-names = "top", ++ "csid0", + "csid1", + "csiphy0", + "csiphy1", + "csitpg0", + "csitpg1", +- "top", + "vfe0", + "vfe1"; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch b/queue-6.18/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch new file mode 100644 index 0000000000..609c3d0d25 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch @@ -0,0 +1,39 @@ +From 58c1f9b4a64546a70e77a7bbb3ca16c5dfe428e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Sep 2025 15:57:01 +0200 +Subject: arm64: dts: qcom: qcm6490-fairphone-fp5: Add supplies to simple-fb + node + +From: Luca Weiss + +[ Upstream commit 3d4142cac46b4dde4e60908c509c4cf107067114 ] + +Add the OLED power supplies to the simple-framebuffer node, so that +the regulators don't get turned off while the simple-fb is being used. + +Fixes: c365a026155c ("arm64: dts: qcom: qcm6490-fairphone-fp5: Enable display") +Signed-off-by: Luca Weiss +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250930-sc7280-dts-misc-v1-1-5a45923ef705@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +index 519e458e1a890..36d5750584831 100644 +--- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts ++++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +@@ -47,6 +47,8 @@ framebuffer0: framebuffer@a000000 { + stride = <(1224 * 4)>; + format = "a8r8g8b8"; + clocks = <&gcc GCC_DISP_HF_AXI_CLK>; ++ vci-supply = <&vreg_oled_vci>; ++ dvdd-supply = <&vreg_oled_dvdd>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch b/queue-6.18/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch new file mode 100644 index 0000000000..1f764c620d --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch @@ -0,0 +1,43 @@ +From f4589cd2f945679057abc54138651174ac58f982 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 11:06:33 +0200 +Subject: arm64: dts: qcom: qcm6490-shift-otter: Add missing reserved-memory + +From: Alexander Martinz + +[ Upstream commit f404fdcb50021fdad6bc734d69468cc777901a80 ] + +It seems we also need to reserve a region of 81 MiB called "removed_mem" +otherwise we can easily hit memory errors with higher RAM usage. + +Fixes: 249666e34c24 ("arm64: dts: qcom: add QCM6490 SHIFTphone 8") +Signed-off-by: Alexander Martinz +Reviewed-by: Konrad Dybcio +Signed-off-by: Luca Weiss +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251009-otter-further-bringup-v2-3-5bb2f4a02cea@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +index eb8efba1b9dda..cc99925798873 100644 +--- a/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts ++++ b/arch/arm64/boot/dts/qcom/qcm6490-shift-otter.dts +@@ -118,6 +118,11 @@ cdsp_mem: cdsp@88f00000 { + no-map; + }; + ++ removed_mem: removed@c0000000 { ++ reg = <0x0 0xc0000000 0x0 0x5100000>; ++ no-map; ++ }; ++ + rmtfs_mem: rmtfs@f8500000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0xf8500000 0x0 0x600000>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch b/queue-6.18/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch new file mode 100644 index 0000000000..edcf48909b --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch @@ -0,0 +1,45 @@ +From a62cef39954e07f50129e15e5d0d37d99f488422 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:40:40 +0530 +Subject: arm64: dts: qcom: qrb2210-rb1: Fix UART3 wakeup IRQ storm + +From: Praveen Talari + +[ Upstream commit 9c92d36b0b1ea8b2a19dbe0416434f3491dbfaaf ] + +For BT use cases, pins are configured with pull-up state in sleep state +to avoid noise. If IRQ type is configured as level high and the GPIO line +is also in a high state, it causes continuous interrupt assertions leading +to an IRQ storm when wakeup irq enables at system suspend/runtime suspend. + +Switching to edge-triggered interrupt (IRQ_TYPE_EDGE_FALLING) resolves +this by only triggering on state transitions (high-to-low) rather than +maintaining sensitivity to the static level state, effectively preventing +the continuous interrupt condition and eliminating the wakeup IRQ storm. + +Fixes: 9380e0a1d449 ("arm64: dts: qcom: qrb2210-rb1: add Bluetooth support") +Signed-off-by: Praveen Talari +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251110101043.2108414-2-praveen.talari@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/qrb2210-rb1.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +index 67ba508e92ba1..3eedfb2cf4799 100644 +--- a/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts ++++ b/arch/arm64/boot/dts/qcom/qrb2210-rb1.dts +@@ -649,7 +649,7 @@ key_volp_n: key-volp-n-state { + &uart3 { + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 330 IRQ_TYPE_LEVEL_HIGH>, +- <&tlmm 11 IRQ_TYPE_LEVEL_HIGH>; ++ <&tlmm 11 IRQ_TYPE_EDGE_FALLING>; + pinctrl-0 = <&uart3_default>; + pinctrl-1 = <&uart3_sleep>; + pinctrl-names = "default", "sleep"; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sc8280xp-fix-shifted-gpi-dma-channels.patch b/queue-6.18/arm64-dts-qcom-sc8280xp-fix-shifted-gpi-dma-channels.patch new file mode 100644 index 0000000000..572b0210dd --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sc8280xp-fix-shifted-gpi-dma-channels.patch @@ -0,0 +1,503 @@ +From ae66c19a36de200886ae0b160fc741e529736189 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 19:55:05 +0800 +Subject: arm64: dts: qcom: sc8280xp: Fix shifted GPI DMA channels + +From: Pengyu Luo + +[ Upstream commit fb48d3f3abba9a7bca2814fa2e9db8ac5b9e16b9 ] + +The GPI DMA channels in sc8280xp.dtsi are wrong. Let's fix it. + +Origianl patch was rebased to the linux-next and formated to a new +patch again later, then it got the GPI DMA channels in the new patch +shifted. + +Fixes: 71b12166a2be ("arm64: dts: qcom: sc8280xp: Describe GPI DMA controller nodes") +Signed-off-by: Pengyu Luo +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251013115506.103649-1-mitltlatltl@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sc8280xp.dtsi | 170 ++++++++++++------------- + 1 file changed, 85 insertions(+), 85 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +index 279e5e6beae20..963ce2362a52e 100644 +--- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi ++++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +@@ -967,8 +967,8 @@ i2c16: i2c@880000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, +- <&gpi_dma2 1 6 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, ++ <&gpi_dma2 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -989,8 +989,8 @@ spi16: spi@880000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, +- <&gpi_dma2 1 0 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1011,8 +1011,8 @@ i2c17: i2c@884000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, +- <&gpi_dma2 1 0 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, ++ <&gpi_dma2 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1033,8 +1033,8 @@ spi17: spi@884000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, +- <&gpi_dma2 1 1 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1069,8 +1069,8 @@ i2c18: i2c@888000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, +- <&gpi_dma2 1 1 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, ++ <&gpi_dma2 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1091,8 +1091,8 @@ spi18: spi@888000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, +- <&gpi_dma2 1 2 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1131,8 +1131,8 @@ i2c19: i2c@88c000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, +- <&gpi_dma2 1 2 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, ++ <&gpi_dma2 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1153,8 +1153,8 @@ spi19: spi@88c000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, +- <&gpi_dma2 1 3 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1175,8 +1175,8 @@ i2c20: i2c@890000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, +- <&gpi_dma2 1 3 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, ++ <&gpi_dma2 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1197,8 +1197,8 @@ spi20: spi@890000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, +- <&gpi_dma2 1 4 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1241,8 +1241,8 @@ spi21: spi@894000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, +- <&gpi_dma2 1 4 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1285,8 +1285,8 @@ spi22: spi@898000 { + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, +- <&gpi_dma2 1 5 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, ++ <&gpi_dma2 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1338,7 +1338,7 @@ spi23: spi@89c000 { + }; + }; + +- gpi_dma0: dma-controller@900000 { ++ gpi_dma0: dma-controller@900000 { + compatible = "qcom,sc8280xp-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0 0x00900000 0 0x60000>; + +@@ -1393,8 +1393,8 @@ i2c0: i2c@980000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>, +- <&gpi_dma0 1 7 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1415,8 +1415,8 @@ spi0: spi@980000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 0 QCOM_GPI_I2C>, +- <&gpi_dma0 1 0 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1437,8 +1437,8 @@ i2c1: i2c@984000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 0 QCOM_GPI_SPI>, +- <&gpi_dma0 1 0 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1459,8 +1459,8 @@ spi1: spi@984000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 1 QCOM_GPI_I2C>, +- <&gpi_dma0 1 1 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1481,8 +1481,8 @@ i2c2: i2c@988000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 1 QCOM_GPI_SPI>, +- <&gpi_dma0 1 1 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1503,8 +1503,8 @@ spi2: spi@988000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 2 QCOM_GPI_I2C>, +- <&gpi_dma0 1 2 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1539,8 +1539,8 @@ i2c3: i2c@98c000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 2 QCOM_GPI_SPI>, +- <&gpi_dma0 1 2 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1561,8 +1561,8 @@ spi3: spi@98c000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 3 QCOM_GPI_I2C>, +- <&gpi_dma0 1 3 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1583,8 +1583,8 @@ i2c4: i2c@990000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 3 QCOM_GPI_SPI>, +- <&gpi_dma0 1 3 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1605,8 +1605,8 @@ spi4: spi@990000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 4 QCOM_GPI_I2C>, +- <&gpi_dma0 1 4 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1627,8 +1627,8 @@ i2c5: i2c@994000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 4 QCOM_GPI_SPI>, +- <&gpi_dma0 1 4 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1649,8 +1649,8 @@ spi5: spi@994000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 5 QCOM_GPI_I2C>, +- <&gpi_dma0 1 5 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1671,8 +1671,8 @@ i2c6: i2c@998000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 5 QCOM_GPI_SPI>, +- <&gpi_dma0 1 5 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1693,8 +1693,8 @@ spi6: spi@998000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 6 QCOM_GPI_I2C>, +- <&gpi_dma0 1 6 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>, ++ <&gpi_dma0 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1715,8 +1715,8 @@ i2c7: i2c@99c000 { + <&aggre1_noc MASTER_QUP_0 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma0 0 6 QCOM_GPI_SPI>, +- <&gpi_dma0 1 6 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma0 0 7 QCOM_GPI_I2C>, ++ <&gpi_dma0 1 7 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1800,8 +1800,8 @@ i2c8: i2c@a80000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, +- <&gpi_dma1 1 7 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1822,8 +1822,8 @@ spi8: spi@a80000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, +- <&gpi_dma1 1 0 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1844,8 +1844,8 @@ i2c9: i2c@a84000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, +- <&gpi_dma1 1 0 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1866,8 +1866,8 @@ spi9: spi@a84000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, +- <&gpi_dma1 1 1 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1888,8 +1888,8 @@ i2c10: i2c@a88000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, +- <&gpi_dma1 1 1 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1910,8 +1910,8 @@ spi10: spi@a88000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, +- <&gpi_dma1 1 2 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1932,8 +1932,8 @@ i2c11: i2c@a8c000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, +- <&gpi_dma1 1 2 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1954,8 +1954,8 @@ spi11: spi@a8c000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, +- <&gpi_dma1 1 3 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -1976,8 +1976,8 @@ i2c12: i2c@a90000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, +- <&gpi_dma1 1 3 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -1998,8 +1998,8 @@ spi12: spi@a90000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, +- <&gpi_dma1 1 4 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -2020,8 +2020,8 @@ i2c13: i2c@a94000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, +- <&gpi_dma1 1 4 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -2042,8 +2042,8 @@ spi13: spi@a94000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, +- <&gpi_dma1 1 5 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -2064,8 +2064,8 @@ i2c14: i2c@a98000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, +- <&gpi_dma1 1 5 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +@@ -2086,8 +2086,8 @@ spi14: spi@a98000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, +- <&gpi_dma1 1 6 QCOM_GPI_I2C>; ++ dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, ++ <&gpi_dma1 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + +@@ -2108,8 +2108,8 @@ i2c15: i2c@a9c000 { + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + interconnect-names = "qup-core", "qup-config", "qup-memory"; + +- dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, +- <&gpi_dma1 1 6 QCOM_GPI_SPI>; ++ dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, ++ <&gpi_dma1 1 7 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch b/queue-6.18/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch new file mode 100644 index 0000000000..b0f6209eec --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch @@ -0,0 +1,41 @@ +From 6b9f597b45fb1b7a8843ff468d6b5f675b7e139f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Sep 2025 13:20:28 +0200 +Subject: arm64: dts: qcom: sdm845-oneplus: Correct gpio used for slider + +From: Gergo Koteles + +[ Upstream commit d7ec7d34237498fab7a6afed8da4b7139b0e387c ] + +The previous GPIO numbers were wrong. Update them to the correct +ones and fix the label. + +Fixes: 288ef8a42612 ("arm64: dts: sdm845: add oneplus6/6t devices") +Signed-off-by: Gergo Koteles +Signed-off-by: David Heidelberg +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250927-slider-correct-v1-1-fb8cc7fdcedf@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +index dcfffb271fcf3..51a9a276399ac 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +@@ -803,8 +803,8 @@ hall_sensor_default: hall-sensor-default-state { + bias-disable; + }; + +- tri_state_key_default: tri-state-key-default-state { +- pins = "gpio40", "gpio42", "gpio26"; ++ alert_slider_default: alert-slider-default-state { ++ pins = "gpio126", "gpio52", "gpio24"; + function = "gpio"; + drive-strength = <2>; + bias-disable; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch new file mode 100644 index 0000000000..7838d8fbc2 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch @@ -0,0 +1,39 @@ +From e9bc2faef3157d9b241ddb52a5cf8262f9c76bea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 18:32:16 +0200 +Subject: arm64: dts: qcom: sdm845-starqltechn: Fix i2c-gpio node name + +From: Konrad Dybcio + +[ Upstream commit 6030fa06360b8b8d898b66ac156adaaf990b83cb ] + +Fix the following DT checker warning: + +$nodename:0: 'i2c21' does not match '^i2c(@.+|-[a-z0-9]+)?$' + +Fixes: 3a4600448bef ("arm64: dts: qcom: sdm845-starqltechn: add display PMIC") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251015-topic-starltechn_i2c_gpio-v1-1-6d303184ee87@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index 215e1491f3e9a..493c69e991746 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -158,7 +158,7 @@ rmtfs_mem: rmtfs-mem@fde00000 { + }; + }; + +- i2c21 { ++ i2c-21 { + compatible = "i2c-gpio"; + sda-gpios = <&tlmm 127 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + scl-gpios = <&tlmm 128 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch new file mode 100644 index 0000000000..8851940b8e --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch @@ -0,0 +1,71 @@ +From 6d098ca287caae450f752e6afdda9b3d840a1d4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:13:27 +0300 +Subject: arm64: dts: qcom: sdm845-starqltechn: fix max77705 interrupts + +From: Dzmitry Sankouski + +[ Upstream commit 4372b15d89e253e40816f0bde100890cddd25a81 ] + +Since max77705 has a register, which indicates interrupt source, it acts +as an interrupt controller. + +Direct MAX77705's subdevices to use the IC's internal interrupt +controller, instead of listening to every interrupt fired by the +chip towards the host device. + +Fixes: 7a88a931d095 ("arm64: dts: qcom: sdm845-starqltechn: add max77705 PMIC") +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Dzmitry Sankouski +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250926-starqltechn-correct_max77705_nodes-v5-2-c6ab35165534@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + .../boot/dts/qcom/sdm845-samsung-starqltechn.dts | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index 45c7aa0f602d8..215e1491f3e9a 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -599,11 +599,13 @@ &uart9 { + &i2c14 { + status = "okay"; + +- pmic@66 { ++ max77705: pmic@66 { + compatible = "maxim,max77705"; + reg = <0x66>; ++ #interrupt-cells = <1>; + interrupt-parent = <&pm8998_gpios>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-controller; + pinctrl-0 = <&pmic_int_default>; + pinctrl-names = "default"; + +@@ -644,8 +646,8 @@ max77705_charger: charger@69 { + reg = <0x69>; + compatible = "maxim,max77705-charger"; + monitored-battery = <&battery>; +- interrupt-parent = <&pm8998_gpios>; +- interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&max77705>; ++ interrupts = <0>; + }; + + fuel-gauge@36 { +@@ -653,8 +655,8 @@ fuel-gauge@36 { + compatible = "maxim,max77705-battery"; + power-supplies = <&max77705_charger>; + maxim,rsns-microohm = <5000>; +- interrupt-parent = <&pm8998_gpios>; +- interrupts = <11 IRQ_TYPE_LEVEL_LOW>; ++ interrupt-parent = <&max77705>; ++ interrupts = <2>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch new file mode 100644 index 0000000000..32e156e74c --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch @@ -0,0 +1,42 @@ +From c10ff046426f3493698df7bbb04ac86091add6fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:13:26 +0300 +Subject: arm64: dts: qcom: sdm845-starqltechn: remove (address|size)-cells + +From: Dzmitry Sankouski + +[ Upstream commit 4133486382364f60ea7e4f2c9070555689d9606e ] + +Drop the unused address/size-cells properties to silence the DT +checker warning: + +pmic@66 (maxim,max77705): '#address-cells', '#size-cells' do not +match any of the regexes: '^pinctrl-[0-9]+$' + +Fixes: 7a88a931d095 ("arm64: dts: qcom: sdm845-starqltechn: add max77705 PMIC") +Reviewed-by: Konrad Dybcio +Signed-off-by: Dzmitry Sankouski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250926-starqltechn-correct_max77705_nodes-v5-1-c6ab35165534@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +index 75a53f0bbebd0..45c7aa0f602d8 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts ++++ b/arch/arm64/boot/dts/qcom/sdm845-samsung-starqltechn.dts +@@ -606,8 +606,6 @@ pmic@66 { + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pmic_int_default>; + pinctrl-names = "default"; +- #address-cells = <1>; +- #size-cells = <0>; + + leds { + compatible = "maxim,max77705-rgb"; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sm8250-samsung-common-correct-reserve.patch b/queue-6.18/arm64-dts-qcom-sm8250-samsung-common-correct-reserve.patch new file mode 100644 index 0000000000..751cdfbb23 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sm8250-samsung-common-correct-reserve.patch @@ -0,0 +1,43 @@ +From c0a674a0f77bea45e1674b7c5dc9b6d9a598fd55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 16:21:29 -0400 +Subject: arm64: dts: qcom: sm8250-samsung-common: correct reserved pins +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Eric Gonçalves + +[ Upstream commit 42e56b53a1919dbbd78e140a9f8223f8136ac360 ] + +The S20 series has additional reserved pins for the fingerprint sensor, +GPIO 20-23. Correct it by adding them into gpio-reserved-ranges. + +Fixes: 6657fe9e9f23 ("arm64: dts: qcom: add initial support for Samsung Galaxy S20 FE") +Signed-off-by: Eric Gonçalves +Reviewed-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251016202129.226449-1-ghatto404@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi b/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi +index cf3d917addd82..ef7ea4f72bf99 100644 +--- a/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8250-samsung-common.dtsi +@@ -159,7 +159,8 @@ &pon_resin { + }; + + &tlmm { +- gpio-reserved-ranges = <40 4>; /* I2C (Unused) */ ++ gpio-reserved-ranges = <20 4>, /* SPI (fingerprint scanner) */ ++ <40 4>; /* Unused */ + }; + + &usb_1 { +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch b/queue-6.18/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch new file mode 100644 index 0000000000..47b88e3fd3 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch @@ -0,0 +1,47 @@ +From 66e9646610c8a13f726197229af9c3987c5522f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 20:53:44 +0200 +Subject: arm64: dts: qcom: sm8650: set ufs as dma coherent + +From: Neil Armstrong + +[ Upstream commit c2703c90161b45bca5b65f362adbae02ed71fcc1 ] + +The UFS device is ovbiously dma coherent like the other IOMMU devices +like usb, mmc, ... let's fix this by adding the flag. + +To be sure an extensive test has been performed to be sure it's +safe, as downstream uses this flag for UFS as well. + +As an experiment, I checked how the dma-coherent could impact +the UFS bandwidth, and it happens the max bandwidth on cached +write is slighly highter (up to 10%) while using less cpu time +since cache sync/flush is skipped. + +Fixes: 10e024671295 ("arm64: dts: qcom: sm8650: add interconnect dependent device nodes") +Signed-off-by: Neil Armstrong +Reviewed-by: Krzysztof Kozlowski +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251007-topic-sm8650-upstream-ufs-dma-coherent-v1-1-f3cfeaee04ce@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8650.dtsi | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi +index ebf1971b1bfbe..3b03c13539386 100644 +--- a/arch/arm64/boot/dts/qcom/sm8650.dtsi ++++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi +@@ -3988,6 +3988,8 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + + iommus = <&apps_smmu 0x60 0>; + ++ dma-coherent; ++ + lanes-per-direction = <2>; + qcom,ice = <&ice>; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-sm8750-mtp-move-pcie-gpios-to-pciepor.patch b/queue-6.18/arm64-dts-qcom-sm8750-mtp-move-pcie-gpios-to-pciepor.patch new file mode 100644 index 0000000000..2dab1ffb2c --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-sm8750-mtp-move-pcie-gpios-to-pciepor.patch @@ -0,0 +1,54 @@ +From 5771fc4dfa574d7fedb72ce4d1092c8cf24c2729 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 10:08:55 +0530 +Subject: arm64: dts: qcom: sm8750-mtp: move PCIe GPIOs to pcieport0 node + +From: Krishna Chaitanya Chundru + +[ Upstream commit cc8056a16472d186140d1a66ed5648cee41f4379 ] + +Relocate the wake-gpios and perst-gpios properties from the pcie0 +controller node to the pcieport0 node. These GPIOs are associated with +the PCIe root port and should reside under the pcieport0 node. + +Also rename perst-gpios to reset-gpios to match the expected property name +in the PCIe port node. + +Fixes: 141714e163bb ("arm64: dts: qcom: sm8750-mtp: Add WiFi and Bluetooth") +Signed-off-by: Krishna Chaitanya Chundru +Reviewed-by: Krzysztof Kozlowski +Tested-by: Krzysztof Kozlowski +Link: https://lore.kernel.org/r/20251008-sm8750-v1-1-daeadfcae980@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sm8750-mtp.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +index 3bbb53b7c71f3..45b5f75815670 100644 +--- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts ++++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +@@ -960,9 +960,6 @@ &pon_resin { + }; + + &pcie0 { +- wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; +- perst-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +- + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + +@@ -977,6 +974,9 @@ &pcie0_phy { + }; + + &pcieport0 { ++ wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; ++ reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; ++ + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-x1-dell-thena-add-missing-pinctrl-for.patch b/queue-6.18/arm64-dts-qcom-x1-dell-thena-add-missing-pinctrl-for.patch new file mode 100644 index 0000000000..0baec18d57 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-x1-dell-thena-add-missing-pinctrl-for.patch @@ -0,0 +1,43 @@ +From 25fcd4aa9728bf2213945e82ae072b7b6a66ecc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 19:40:08 -0300 +Subject: arm64: dts: qcom: x1-dell-thena: Add missing pinctrl for eDP HPD + +From: Val Packett + +[ Upstream commit 1bdfe3edd4c862f97ac65b60da1db999981fc52a ] + +The commit a41d23142d87 ("arm64: dts: qcom: x1e80100-dell-xps13-9345: +Add missing pinctrl for eDP HPD") has applied this change to a very +similar machine, so apply it here too. + +This allows us not to rely on the boot firmware to set up the pinctrl +for the eDP HPD line of the internal display. + +Fixes: e7733b42111c ("arm64: dts: qcom: Add support for Dell Inspiron 7441 / Latitude 7455") +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Val Packett +Link: https://lore.kernel.org/r/20251012224706.14311-1-val@packett.cool +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +index cc64558ed5e6f..9df66295660c3 100644 +--- a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +@@ -1039,6 +1039,9 @@ &mdss_dp1_out { + &mdss_dp3 { + /delete-property/ #sound-dai-cells; + ++ pinctrl-0 = <&edp0_hpd_default>; ++ pinctrl-names = "default"; ++ + status = "okay"; + + aux-bus { +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-x1-dell-thena-remove-dp-data-lanes.patch b/queue-6.18/arm64-dts-qcom-x1-dell-thena-remove-dp-data-lanes.patch new file mode 100644 index 0000000000..1ef28eb3fa --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-x1-dell-thena-remove-dp-data-lanes.patch @@ -0,0 +1,49 @@ +From 3e0b507fafffc5a757d1ec3b038227c8dc3af027 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 19:48:07 -0300 +Subject: arm64: dts: qcom: x1-dell-thena: remove dp data-lanes + +From: Val Packett + +[ Upstream commit 147d5eefab8f0e17e9951fb5e0c4c77bada34558 ] + +The commit 458de584248a ("arm64: dts: qcom: x1e80100: move dp0/1/2 +data-lanes to SoC dtsi") has landed before this file was added, so +the data-lanes lines here remained. + +Remove them to enable 4-lane DP on the X1E Dell Inspiron/Latitude. + +Fixes: e7733b42111c ("arm64: dts: qcom: Add support for Dell Inspiron 7441 / Latitude 7455") +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Val Packett +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251012224909.14988-1-val@packett.cool +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +index 9df66295660c3..847b678f040c0 100644 +--- a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +@@ -1023,7 +1023,6 @@ &mdss_dp0 { + }; + + &mdss_dp0_out { +- data-lanes = <0 1>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + }; + +@@ -1032,7 +1031,6 @@ &mdss_dp1 { + }; + + &mdss_dp1_out { +- data-lanes = <0 1>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch b/queue-6.18/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch new file mode 100644 index 0000000000..b14430be33 --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch @@ -0,0 +1,39 @@ +From b5807d78c184259b9d0b0ca9cd4b3c9fb52d3e64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 16:20:18 +0530 +Subject: arm64: dts: qcom: x1e80100: Add missing quirk for HS only USB + controller + +From: Krishna Kurapati + +[ Upstream commit 6b3e8a5d6c88609d9ce93789524f818cca0aa485 ] + +The PIPE clock is provided by the USB3 PHY, which is predictably not +connected to the HS-only controller. Add "qcom,select-utmi-as-pipe-clk" +quirk to HS only USB controller to disable pipe clock requirement. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Abel Vesa +Link: https://lore.kernel.org/r/20251024105019.2220832-2-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index 6beef835c33ad..662ad694cd914 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4922,6 +4922,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + interconnect-names = "usb-ddr", + "apps-usb"; + ++ qcom,select-utmi-as-pipe-clk; + wakeup-source; + + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch b/queue-6.18/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch new file mode 100644 index 0000000000..efab71f99e --- /dev/null +++ b/queue-6.18/arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch @@ -0,0 +1,53 @@ +From eed592cc596f0c21e0c2c66577c384c952fc86dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 19 Oct 2025 17:26:30 +0530 +Subject: arm64: dts: qcom: x1e80100: Fix compile warnings for USB HS + controller + +From: Krishna Kurapati + +[ Upstream commit 0dab10c38282e6ef87ef88efb99d4106cce7ed33 ] + +With W=1, the following error comes up: + +Warning (graph_child_address): /soc@0/usb@a2f8800/usb@a200000/ports: graph node has single child node 'port@0', #address-cells/#size-cells are not necessary + +This could be since the controller is only HS capable and only one port +node is added. + +Fixes: 4af46b7bd66f ("arm64: dts: qcom: x1e80100: Add USB nodes") +Signed-off-by: Krishna Kurapati +Reviewed-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20251019115630.2222720-1-krishna.kurapati@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/x1e80100.dtsi | 11 ++--------- + 1 file changed, 2 insertions(+), 9 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +index 51576d9c935de..6beef835c33ad 100644 +--- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi ++++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi +@@ -4939,15 +4939,8 @@ usb_2_dwc3: usb@a200000 { + + dma-coherent; + +- ports { +- #address-cells = <1>; +- #size-cells = <0>; +- +- port@0 { +- reg = <0>; +- +- usb_2_dwc3_hs: endpoint { +- }; ++ port { ++ usb_2_dwc3_hs: endpoint { + }; + }; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch b/queue-6.18/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch new file mode 100644 index 0000000000..563bb808b0 --- /dev/null +++ b/queue-6.18/arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch @@ -0,0 +1,60 @@ +From 4fd65d59baea497ed68c1a52baf6a82478f9b8ab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 19:45:53 +0100 +Subject: arm64: dts: renesas: sparrow-hawk: Fix full-size DP connector node + name and labels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Marek Vasut + +[ Upstream commit 9d22a34a016313137b9e534a918f1f9aa790aa69 ] + +The DisplayPort connector on Retronix R-Car V4H Sparrow Hawk board +is a full-size DisplayPort connector. Fix the copy-paste error and +update the DT node name and labels accordingly. No functional change. + +Fixes: a719915e76f2 ("arm64: dts: renesas: r8a779g3: Add Retronix R-Car V4H Sparrow Hawk board support") +Signed-off-by: Marek Vasut +Reviewed-by: Niklas Söderlund +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251027184604.34550-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +index 1da8e476b2193..ff07d984cbf29 100644 +--- a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts ++++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +@@ -119,13 +119,13 @@ memory@600000000 { + }; + + /* Page 27 / DSI to Display */ +- mini-dp-con { ++ dp-con { + compatible = "dp-connector"; + label = "CN6"; + type = "full-size"; + + port { +- mini_dp_con_in: endpoint { ++ dp_con_in: endpoint { + remote-endpoint = <&sn65dsi86_out>; + }; + }; +@@ -407,7 +407,7 @@ sn65dsi86_in: endpoint { + port@1 { + reg = <1>; + sn65dsi86_out: endpoint { +- remote-endpoint = <&mini_dp_con_in>; ++ remote-endpoint = <&dp_con_in>; + }; + }; + }; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch b/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch new file mode 100644 index 0000000000..c20f1035e0 --- /dev/null +++ b/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch @@ -0,0 +1,48 @@ +From f69251859dfb690ea122ba964a16fe8f759a1315 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:30 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 3069ff1930aa71e125874c780ffaa6caeda5800a ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is +vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1] +Describe this supply. + +[1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-3-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 428c6f0232a34..041a0fff22ccb 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -233,6 +233,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcc_3v3_pmu>; + }; + }; + +@@ -600,7 +601,7 @@ regulator-state-mem { + }; + }; + +- vcc_3v3_s3: dcdc-reg8 { ++ vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12419 b/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12419 new file mode 100644 index 0000000000..0e378bc0af --- /dev/null +++ b/queue-6.18/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12419 @@ -0,0 +1,38 @@ +From ccce65262eb977aa88ccdb8451b004aea6f3cef5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:31 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 3C + +From: FUKAUMI Naoki + +[ Upstream commit 260316d35cf8f8606c5ed7a349cc92e1e71d8150 ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 3C is +vcca1v8_pmu. [1] Describe this supply. + +[1] https://dl.radxa.com/rock3/docs/hw/3c/v1400/radxa_rock_3c_v1400_schematic.pdf p.13 + +Fixes: ee219017ddb50 ("arm64: dts: rockchip: Add Radxa ROCK 3C") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-4-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +index 6224d72813e59..80ac40555e023 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3566-rock-3c.dts +@@ -466,6 +466,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcca1v8_pmu>; + }; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-rockchip-fix-usb-type-c-host-mode-for-radx.patch b/queue-6.18/arm64-dts-rockchip-fix-usb-type-c-host-mode-for-radx.patch new file mode 100644 index 0000000000..24ca9005b5 --- /dev/null +++ b/queue-6.18/arm64-dts-rockchip-fix-usb-type-c-host-mode-for-radx.patch @@ -0,0 +1,113 @@ +From 0bd4d80768203f9b6c7e718f2e2de978e5cf2b45 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:52:27 +0000 +Subject: arm64: dts: rockchip: Fix USB Type-C host mode for Radxa ROCK 5B+/5T + +From: FUKAUMI Naoki + +[ Upstream commit fbf90d1b697faf61bb8b3ed72be6a8ebeb09de3d ] + +The Radxa ROCK 5B+/5T USB Type-C port supports Dual Role Data and +should also act as a host. However, currently, when acting as a host, +only self-powered devices work. + +Since the ROCK 5B+ supports Dual Role Power, set the power-role +property to "dual" and the try-power-role property to "sink". (along +with related properties) + +The ROCK 5T should only support the "source" power-role. + +This allows the port to act as a host, supply power to the port, and +allow bus-powered devices to work. + +Note that on the ROCK 5T, with this patch applied, it has been +observed that some bus-powered devices do not work correctly. Also, +it has been observed that after connecting a device (and the data-role +switches to host), connecting a host device does not switch the +data-role back to the device role. These issues should be addressed +separately. + +Note that there is a separate known issue where USB 3.0 SuperSpeed +devices do not work when oriented in reverse. This issue should also be +addressed separately. (USB 2.0/1.1 devices work in both orientations) + +Fixes: 67b2c15d8fb3c ("arm64: dts: rockchip: add USB-C support for ROCK 5B/5B+/5T") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251104085227.820-1-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi | 4 ++-- + arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts | 5 +++++ + arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts | 4 ++++ + arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts | 4 ++++ + 4 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +index 3bbe78810ec6f..7aac77dfc5f16 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +@@ -331,12 +331,12 @@ usb_con: connector { + data-role = "dual"; + /* fusb302 supports PD Rev 2.0 Ver 1.2 */ + pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>; +- power-role = "sink"; +- try-power-role = "sink"; + op-sink-microwatt = <1000000>; + sink-pdos = + , + ; ++ source-pdos = ++ ; + + altmodes { + displayport { +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts +index 5e984a44120e4..07a840d9b3859 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-plus.dts +@@ -110,6 +110,11 @@ vcc5v0_host_en: vcc5v0-host-en { + }; + }; + ++&usb_con { ++ power-role = "dual"; ++ try-power-role = "sink"; ++}; ++ + &usbdp_phy0 { + pinctrl-names = "default"; + pinctrl-0 = <&usbc_sbu_dc>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +index 8ef01010d985b..da13dafcbc823 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b.dts +@@ -49,6 +49,10 @@ vcc5v0_host_en: vcc5v0-host-en { + }; + }; + ++&usb_con { ++ power-role = "sink"; ++}; ++ + &usbdp_phy0 { + pinctrl-names = "default"; + pinctrl-0 = <&usbc_sbu_dc>; +diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts +index c1763835f53d4..0dd90c744380b 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5t.dts +@@ -130,6 +130,10 @@ usbc_sbu_dc: usbc-sbu-dc { + }; + }; + ++&usb_con { ++ power-role = "source"; ++}; ++ + &usbdp_phy0 { + pinctrl-names = "default"; + pinctrl-0 = <&usbc_sbu_dc>; +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch b/queue-6.18/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch new file mode 100644 index 0000000000..e17add8f4b --- /dev/null +++ b/queue-6.18/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch @@ -0,0 +1,58 @@ +From 34cdc2b4c850c7267b9f16000bf3bd555f1c5c25 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:29 +0000 +Subject: arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa + ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 92e6e0b0e595afdda6296c760551ad3ffe9d5231 ] + +The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the +i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0 +bus. + +[1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-2-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 19a08f7794e67..428c6f0232a34 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -228,6 +228,12 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; ++ ++ eeprom: eeprom@50 { ++ compatible = "belling,bl24c16a", "atmel,24c16"; ++ reg = <0x50>; ++ pagesize = <16>; ++ }; + }; + + &i2c2 { +@@ -249,12 +255,6 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; +- +- eeprom: eeprom@50 { +- compatible = "belling,bl24c16a", "atmel,24c16"; +- reg = <0x50>; +- pagesize = <16>; +- }; + }; + + &i2c3 { +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch b/queue-6.18/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch new file mode 100644 index 0000000000..f43b8e4066 --- /dev/null +++ b/queue-6.18/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch @@ -0,0 +1,40 @@ +From fc81d19f9e37807c038b0494987851c4e6797562 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 14:33:42 -0500 +Subject: arm64: dts: ti: k3-am62p: Fix memory ranges for GPU + +From: Randolph Sapp + +[ Upstream commit 76546090b1726118cd6fb3db7159fc2a3fdda8a0 ] + +Update the memory region listed in the k3-am62p.dtsi for the BXS-4-64 +GPU to match the Main Memory Map described in the TRM [1]. + +[1] https://www.ti.com/lit/ug/spruj83b/spruj83b.pdf + +Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs") +Signed-off-by: Randolph Sapp +Reviewed-by: Michael Walle +Link: https://patch.msgid.link/20250919193341.707660-2-rs@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +index 75a15c368c11b..dd24c40c7965d 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +@@ -59,7 +59,7 @@ cbass_main: bus@f0000 { + <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ + <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ +- <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ ++ <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ + <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ + <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ + <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ +-- +2.51.0 + diff --git a/queue-6.18/arm64-dts-ti-k3-j784s4-fix-i2c-pinmux-pull-configura.patch b/queue-6.18/arm64-dts-ti-k3-j784s4-fix-i2c-pinmux-pull-configura.patch new file mode 100644 index 0000000000..630fdc05b6 --- /dev/null +++ b/queue-6.18/arm64-dts-ti-k3-j784s4-fix-i2c-pinmux-pull-configura.patch @@ -0,0 +1,79 @@ +From 4d91c16a38c366db8f89e80c600382252078f260 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 17:56:33 +0530 +Subject: arm64: dts: ti: k3-j784s4: Fix I2C pinmux pull configuration + +From: Aniket Limaye + +[ Upstream commit 671c852fc53d1b6f5eccdb03c1889a484c9d1996 ] + +The I2C pins for some of the instances on J784S4/J742S2/AM69 are +configured as PIN_INPUT_PULLUP while these pins are open-drain type and +do not support internal pull-ups [0][1][2]. The pullup configuration +bits in the corresponding padconfig registers are reserved and any +writes to them have no effect and readback checks on those bits fail. + +Update the pinmux settings to use PIN_INPUT instead of PIN_INPUT_PULLUP +to reflect the correct hardware behaviour. + +[0]: https://www.ti.com/lit/gpn/tda4ah-q1 (J784S4 Datasheet: Table 5-1. Pin Attributes) +[1]: https://www.ti.com/lit/gpn/tda4ape-q1 (J742S2 Datasheet: Table 5-1. Pin Attributes) +[2]: https://www.ti.com/lit/gpn/am69a (AM69 Datasheet: Table 5-1. Pin Attributes) + +Fixes: e20a06aca5c9 ("arm64: dts: ti: Add support for J784S4 EVM board") +Fixes: 635fb18ba008 ("arch: arm64: dts: Add support for AM69 Starter Kit") +Fixes: 0ec1a48d99dd ("arm64: dts: ti: k3-am69-sk: Add pinmux for RPi Header") +Signed-off-by: Aniket Limaye +Reviewed-by: Udit Kumar +Link: https://patch.msgid.link/20251022122638.234367-1-a-limaye@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am69-sk.dts | 8 ++++---- + arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am69-sk.dts b/arch/arm64/boot/dts/ti/k3-am69-sk.dts +index 5896e57b5b9ed..0e2d12cb051da 100644 +--- a/arch/arm64/boot/dts/ti/k3-am69-sk.dts ++++ b/arch/arm64/boot/dts/ti/k3-am69-sk.dts +@@ -236,8 +236,8 @@ J784S4_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AN38) SPI0_CLK.UART8_TXD */ + + main_i2c0_pins_default: main-i2c0-default-pins { + pinctrl-single,pins = < +- J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */ +- J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */ ++ J784S4_IOPAD(0x0e0, PIN_INPUT, 0) /* (AN36) I2C0_SCL */ ++ J784S4_IOPAD(0x0e4, PIN_INPUT, 0) /* (AP37) I2C0_SDA */ + >; + }; + +@@ -416,8 +416,8 @@ J784S4_WKUP_IOPAD(0x088, PIN_OUTPUT, 0) /* (J37) WKUP_GPIO0_12.MCU_UART0_TXD */ + + mcu_i2c0_pins_default: mcu-i2c0-default-pins { + pinctrl-single,pins = < +- J784S4_WKUP_IOPAD(0x0a0, PIN_INPUT_PULLUP, 0) /* (M35) MCU_I2C0_SCL */ +- J784S4_WKUP_IOPAD(0x0a4, PIN_INPUT_PULLUP, 0) /* (G34) MCU_I2C0_SDA */ ++ J784S4_WKUP_IOPAD(0x0a0, PIN_INPUT, 0) /* (M35) MCU_I2C0_SCL */ ++ J784S4_WKUP_IOPAD(0x0a4, PIN_INPUT, 0) /* (G34) MCU_I2C0_SDA */ + >; + }; + +diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi +index 419c1a70e028d..2834f0a8bbee0 100644 +--- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi +@@ -270,8 +270,8 @@ J784S4_IOPAD(0x0d4, PIN_OUTPUT, 11) /* (AN38) SPI0_CLK.UART8_TXD */ + + main_i2c0_pins_default: main-i2c0-default-pins { + pinctrl-single,pins = < +- J784S4_IOPAD(0x0e0, PIN_INPUT_PULLUP, 0) /* (AN36) I2C0_SCL */ +- J784S4_IOPAD(0x0e4, PIN_INPUT_PULLUP, 0) /* (AP37) I2C0_SDA */ ++ J784S4_IOPAD(0x0e0, PIN_INPUT, 0) /* (AN36) I2C0_SCL */ ++ J784S4_IOPAD(0x0e4, PIN_INPUT, 0) /* (AP37) I2C0_SDA */ + >; + }; + +-- +2.51.0 + diff --git a/queue-6.18/arm64-mm-allow-__create_pgd_mapping-to-propagate-pgt.patch b/queue-6.18/arm64-mm-allow-__create_pgd_mapping-to-propagate-pgt.patch new file mode 100644 index 0000000000..2a2e2c6478 --- /dev/null +++ b/queue-6.18/arm64-mm-allow-__create_pgd_mapping-to-propagate-pgt.patch @@ -0,0 +1,479 @@ +From a8db0521c0c0f6858942f6166e6c8bd82988e7c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 10:44:36 +0530 +Subject: arm64/mm: Allow __create_pgd_mapping() to propagate pgtable_alloc() + errors + +From: Chaitanya S Prakash + +[ Upstream commit bfc184cb1ba7226b21ab26f0b220581895c5ac9e ] + +arch_add_memory() is used to hotplug memory into a system but as a part +of its implementation it calls __create_pgd_mapping(), which uses +pgtable_alloc() in order to build intermediate page tables. As this path +was initally only used during early boot pgtable_alloc() is designed to +BUG_ON() on failure. However, in the event that memory hotplug is +attempted when the system's memory is extremely tight and the allocation +were to fail, it would lead to panicking the system, which is not +desirable. Hence update __create_pgd_mapping and all it's callers to be +non void and propagate -ENOMEM on allocation failure to allow system to +fail gracefully. + +But during early boot if there is an allocation failure, we want the +system to panic, hence create a wrapper around __create_pgd_mapping() +called early_create_pgd_mapping() which is designed to panic, if ret +is non zero value. All the init calls are updated to use this wrapper +rather than the modified __create_pgd_mapping() to restore +functionality. + +Fixes: 4ab215061554 ("arm64: Add memory hotplug support") +Reviewed-by: Dev Jain +Reviewed-by: Ryan Roberts +Reviewed-by: Kevin Brodsky +Signed-off-by: Chaitanya S Prakash +Signed-off-by: Linu Cherian +Reviewed-by: Anshuman Khandual +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/mmu.c | 214 ++++++++++++++++++++++++++++---------------- + 1 file changed, 136 insertions(+), 78 deletions(-) + +diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c +index 2ba01dc8ef822..aeb6fb25a951a 100644 +--- a/arch/arm64/mm/mmu.c ++++ b/arch/arm64/mm/mmu.c +@@ -49,6 +49,8 @@ + #define NO_CONT_MAPPINGS BIT(1) + #define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */ + ++#define INVALID_PHYS_ADDR (-1ULL) ++ + DEFINE_STATIC_KEY_FALSE(arm64_ptdump_lock_key); + + u64 kimage_voffset __ro_after_init; +@@ -194,11 +196,11 @@ static void init_pte(pte_t *ptep, unsigned long addr, unsigned long end, + } while (ptep++, addr += PAGE_SIZE, addr != end); + } + +-static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, +- unsigned long end, phys_addr_t phys, +- pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, ++ unsigned long end, phys_addr_t phys, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { + unsigned long next; + pmd_t pmd = READ_ONCE(*pmdp); +@@ -213,6 +215,8 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, + pmdval |= PMD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pte_phys = pgtable_alloc(TABLE_PTE); ++ if (pte_phys == INVALID_PHYS_ADDR) ++ return -ENOMEM; + ptep = pte_set_fixmap(pte_phys); + init_clear_pgtable(ptep); + ptep += pte_index(addr); +@@ -244,11 +248,13 @@ static void alloc_init_cont_pte(pmd_t *pmdp, unsigned long addr, + * walker. + */ + pte_clear_fixmap(); ++ ++ return 0; + } + +-static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end, +- phys_addr_t phys, pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags) ++static int init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags) + { + unsigned long next; + +@@ -269,22 +275,29 @@ static void init_pmd(pmd_t *pmdp, unsigned long addr, unsigned long end, + BUG_ON(!pgattr_change_is_safe(pmd_val(old_pmd), + READ_ONCE(pmd_val(*pmdp)))); + } else { +- alloc_init_cont_pte(pmdp, addr, next, phys, prot, +- pgtable_alloc, flags); ++ int ret; ++ ++ ret = alloc_init_cont_pte(pmdp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ if (ret) ++ return ret; + + BUG_ON(pmd_val(old_pmd) != 0 && + pmd_val(old_pmd) != READ_ONCE(pmd_val(*pmdp))); + } + phys += next - addr; + } while (pmdp++, addr = next, addr != end); ++ ++ return 0; + } + +-static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, +- unsigned long end, phys_addr_t phys, +- pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, ++ unsigned long end, phys_addr_t phys, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { ++ int ret; + unsigned long next; + pud_t pud = READ_ONCE(*pudp); + pmd_t *pmdp; +@@ -301,6 +314,8 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, + pudval |= PUD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pmd_phys = pgtable_alloc(TABLE_PMD); ++ if (pmd_phys == INVALID_PHYS_ADDR) ++ return -ENOMEM; + pmdp = pmd_set_fixmap(pmd_phys); + init_clear_pgtable(pmdp); + pmdp += pmd_index(addr); +@@ -320,20 +335,26 @@ static void alloc_init_cont_pmd(pud_t *pudp, unsigned long addr, + (flags & NO_CONT_MAPPINGS) == 0) + __prot = __pgprot(pgprot_val(prot) | PTE_CONT); + +- init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags); ++ ret = init_pmd(pmdp, addr, next, phys, __prot, pgtable_alloc, flags); ++ if (ret) ++ goto out; + + pmdp += pmd_index(next) - pmd_index(addr); + phys += next - addr; + } while (addr = next, addr != end); + ++out: + pmd_clear_fixmap(); ++ ++ return ret; + } + +-static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, +- phys_addr_t phys, pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { ++ int ret = 0; + unsigned long next; + p4d_t p4d = READ_ONCE(*p4dp); + pud_t *pudp; +@@ -346,6 +367,8 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, + p4dval |= P4D_TABLE_PXN; + BUG_ON(!pgtable_alloc); + pud_phys = pgtable_alloc(TABLE_PUD); ++ if (pud_phys == INVALID_PHYS_ADDR) ++ return -ENOMEM; + pudp = pud_set_fixmap(pud_phys); + init_clear_pgtable(pudp); + pudp += pud_index(addr); +@@ -375,8 +398,10 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, + BUG_ON(!pgattr_change_is_safe(pud_val(old_pud), + READ_ONCE(pud_val(*pudp)))); + } else { +- alloc_init_cont_pmd(pudp, addr, next, phys, prot, +- pgtable_alloc, flags); ++ ret = alloc_init_cont_pmd(pudp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ if (ret) ++ goto out; + + BUG_ON(pud_val(old_pud) != 0 && + pud_val(old_pud) != READ_ONCE(pud_val(*pudp))); +@@ -384,14 +409,18 @@ static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, + phys += next - addr; + } while (pudp++, addr = next, addr != end); + ++out: + pud_clear_fixmap(); ++ ++ return ret; + } + +-static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, +- phys_addr_t phys, pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, ++ phys_addr_t phys, pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { ++ int ret; + unsigned long next; + pgd_t pgd = READ_ONCE(*pgdp); + p4d_t *p4dp; +@@ -404,6 +433,8 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, + pgdval |= PGD_TABLE_PXN; + BUG_ON(!pgtable_alloc); + p4d_phys = pgtable_alloc(TABLE_P4D); ++ if (p4d_phys == INVALID_PHYS_ADDR) ++ return -ENOMEM; + p4dp = p4d_set_fixmap(p4d_phys); + init_clear_pgtable(p4dp); + p4dp += p4d_index(addr); +@@ -418,8 +449,10 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, + + next = p4d_addr_end(addr, end); + +- alloc_init_pud(p4dp, addr, next, phys, prot, +- pgtable_alloc, flags); ++ ret = alloc_init_pud(p4dp, addr, next, phys, prot, ++ pgtable_alloc, flags); ++ if (ret) ++ goto out; + + BUG_ON(p4d_val(old_p4d) != 0 && + p4d_val(old_p4d) != READ_ONCE(p4d_val(*p4dp))); +@@ -427,15 +460,19 @@ static void alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, + phys += next - addr; + } while (p4dp++, addr = next, addr != end); + ++out: + p4d_clear_fixmap(); ++ ++ return ret; + } + +-static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, +- unsigned long virt, phys_addr_t size, +- pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { ++ int ret; + unsigned long addr, end, next; + pgd_t *pgdp = pgd_offset_pgd(pgdir, virt); + +@@ -444,7 +481,7 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, + * within a page, we cannot map the region as the caller expects. + */ + if (WARN_ON((phys ^ virt) & ~PAGE_MASK)) +- return; ++ return -EINVAL; + + phys &= PAGE_MASK; + addr = virt & PAGE_MASK; +@@ -452,25 +489,45 @@ static void __create_pgd_mapping_locked(pgd_t *pgdir, phys_addr_t phys, + + do { + next = pgd_addr_end(addr, end); +- alloc_init_p4d(pgdp, addr, next, phys, prot, pgtable_alloc, +- flags); ++ ret = alloc_init_p4d(pgdp, addr, next, phys, prot, pgtable_alloc, ++ flags); ++ if (ret) ++ return ret; + phys += next - addr; + } while (pgdp++, addr = next, addr != end); ++ ++ return 0; + } + +-static void __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, +- unsigned long virt, phys_addr_t size, +- pgprot_t prot, +- phys_addr_t (*pgtable_alloc)(enum pgtable_type), +- int flags) ++static int __create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) + { ++ int ret; ++ + mutex_lock(&fixmap_lock); +- __create_pgd_mapping_locked(pgdir, phys, virt, size, prot, +- pgtable_alloc, flags); ++ ret = __create_pgd_mapping_locked(pgdir, phys, virt, size, prot, ++ pgtable_alloc, flags); + mutex_unlock(&fixmap_lock); ++ ++ return ret; + } + +-#define INVALID_PHYS_ADDR (-1ULL) ++static void early_create_pgd_mapping(pgd_t *pgdir, phys_addr_t phys, ++ unsigned long virt, phys_addr_t size, ++ pgprot_t prot, ++ phys_addr_t (*pgtable_alloc)(enum pgtable_type), ++ int flags) ++{ ++ int ret; ++ ++ ret = __create_pgd_mapping(pgdir, phys, virt, size, prot, pgtable_alloc, ++ flags); ++ if (ret) ++ panic("Failed to create page tables\n"); ++} + + static phys_addr_t __pgd_pgtable_alloc(struct mm_struct *mm, gfp_t gfp, + enum pgtable_type pgtable_type) +@@ -511,21 +568,13 @@ try_pgd_pgtable_alloc_init_mm(enum pgtable_type pgtable_type, gfp_t gfp) + static phys_addr_t __maybe_unused + pgd_pgtable_alloc_init_mm(enum pgtable_type pgtable_type) + { +- phys_addr_t pa; +- +- pa = __pgd_pgtable_alloc(&init_mm, GFP_PGTABLE_KERNEL, pgtable_type); +- BUG_ON(pa == INVALID_PHYS_ADDR); +- return pa; ++ return __pgd_pgtable_alloc(&init_mm, GFP_PGTABLE_KERNEL, pgtable_type); + } + + static phys_addr_t + pgd_pgtable_alloc_special_mm(enum pgtable_type pgtable_type) + { +- phys_addr_t pa; +- +- pa = __pgd_pgtable_alloc(NULL, GFP_PGTABLE_KERNEL, pgtable_type); +- BUG_ON(pa == INVALID_PHYS_ADDR); +- return pa; ++ return __pgd_pgtable_alloc(NULL, GFP_PGTABLE_KERNEL, pgtable_type); + } + + static void split_contpte(pte_t *ptep) +@@ -935,8 +984,8 @@ void __init create_mapping_noalloc(phys_addr_t phys, unsigned long virt, + &phys, virt); + return; + } +- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, +- NO_CONT_MAPPINGS); ++ early_create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, ++ NO_CONT_MAPPINGS); + } + + void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, +@@ -950,8 +999,8 @@ void __init create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys, + if (page_mappings_only) + flags = NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + +- __create_pgd_mapping(mm->pgd, phys, virt, size, prot, +- pgd_pgtable_alloc_special_mm, flags); ++ early_create_pgd_mapping(mm->pgd, phys, virt, size, prot, ++ pgd_pgtable_alloc_special_mm, flags); + } + + static void update_mapping_prot(phys_addr_t phys, unsigned long virt, +@@ -963,8 +1012,8 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt, + return; + } + +- __create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, +- NO_CONT_MAPPINGS); ++ early_create_pgd_mapping(init_mm.pgd, phys, virt, size, prot, NULL, ++ NO_CONT_MAPPINGS); + + /* flush the TLBs after updating live kernel mappings */ + flush_tlb_kernel_range(virt, virt + size); +@@ -973,8 +1022,8 @@ static void update_mapping_prot(phys_addr_t phys, unsigned long virt, + static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start, + phys_addr_t end, pgprot_t prot, int flags) + { +- __create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, +- prot, early_pgtable_alloc, flags); ++ early_create_pgd_mapping(pgdp, start, __phys_to_virt(start), end - start, ++ prot, early_pgtable_alloc, flags); + } + + void __init mark_linear_text_alias_ro(void) +@@ -1207,6 +1256,8 @@ static int __init __kpti_install_ng_mappings(void *__unused) + remap_fn = (void *)__pa_symbol(idmap_kpti_install_ng_mappings); + + if (!cpu) { ++ int ret; ++ + alloc = __get_free_pages(GFP_ATOMIC | __GFP_ZERO, order); + kpti_ng_temp_pgd = (pgd_t *)(alloc + (levels - 1) * PAGE_SIZE); + kpti_ng_temp_alloc = kpti_ng_temp_pgd_pa = __pa(kpti_ng_temp_pgd); +@@ -1227,9 +1278,11 @@ static int __init __kpti_install_ng_mappings(void *__unused) + // covers the PTE[] page itself, the remaining entries are free + // to be used as a ad-hoc fixmap. + // +- __create_pgd_mapping_locked(kpti_ng_temp_pgd, __pa(alloc), +- KPTI_NG_TEMP_VA, PAGE_SIZE, PAGE_KERNEL, +- kpti_ng_pgd_alloc, 0); ++ ret = __create_pgd_mapping_locked(kpti_ng_temp_pgd, __pa(alloc), ++ KPTI_NG_TEMP_VA, PAGE_SIZE, PAGE_KERNEL, ++ kpti_ng_pgd_alloc, 0); ++ if (ret) ++ panic("Failed to create page tables\n"); + } + + cpu_install_idmap(); +@@ -1282,9 +1335,9 @@ static int __init map_entry_trampoline(void) + + /* Map only the text into the trampoline page table */ + memset(tramp_pg_dir, 0, PGD_SIZE); +- __create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, +- entry_tramp_text_size(), prot, +- pgd_pgtable_alloc_init_mm, NO_BLOCK_MAPPINGS); ++ early_create_pgd_mapping(tramp_pg_dir, pa_start, TRAMP_VALIAS, ++ entry_tramp_text_size(), prot, ++ pgd_pgtable_alloc_init_mm, NO_BLOCK_MAPPINGS); + + /* Map both the text and data into the kernel page table */ + for (i = 0; i < DIV_ROUND_UP(entry_tramp_text_size(), PAGE_SIZE); i++) +@@ -1926,23 +1979,28 @@ int arch_add_memory(int nid, u64 start, u64 size, + if (force_pte_mapping()) + flags |= NO_BLOCK_MAPPINGS | NO_CONT_MAPPINGS; + +- __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), +- size, params->pgprot, pgd_pgtable_alloc_init_mm, +- flags); ++ ret = __create_pgd_mapping(swapper_pg_dir, start, __phys_to_virt(start), ++ size, params->pgprot, pgd_pgtable_alloc_init_mm, ++ flags); ++ if (ret) ++ goto err; + + memblock_clear_nomap(start, size); + + ret = __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, + params); + if (ret) +- __remove_pgd_mapping(swapper_pg_dir, +- __phys_to_virt(start), size); +- else { +- /* Address of hotplugged memory can be smaller */ +- max_pfn = max(max_pfn, PFN_UP(start + size)); +- max_low_pfn = max_pfn; +- } ++ goto err; ++ ++ /* Address of hotplugged memory can be smaller */ ++ max_pfn = max(max_pfn, PFN_UP(start + size)); ++ max_low_pfn = max_pfn; ++ ++ return 0; + ++err: ++ __remove_pgd_mapping(swapper_pg_dir, ++ __phys_to_virt(start), size); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/arm64-pageattr-propagate-return-value-from-__change_.patch b/queue-6.18/arm64-pageattr-propagate-return-value-from-__change_.patch new file mode 100644 index 0000000000..333d99e74a --- /dev/null +++ b/queue-6.18/arm64-pageattr-propagate-return-value-from-__change_.patch @@ -0,0 +1,53 @@ +From 0d547b31025c169cb303b4be7a34b2499021f19e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 11:57:15 +0530 +Subject: arm64/pageattr: Propagate return value from __change_memory_common + +From: Dev Jain + +[ Upstream commit e5efd56fa157d2e7d789949d1d64eccbac18a897 ] + +The rodata=on security measure requires that any code path which does +vmalloc -> set_memory_ro/set_memory_rox must protect the linear map alias +too. Therefore, if such a call fails, we must abort set_memory_* and caller +must take appropriate action; currently we are suppressing the error, and +there is a real chance of such an error arising post commit a166563e7ec3 +("arm64: mm: support large block mapping when rodata=full"). Therefore, +propagate any error to the caller. + +Fixes: a166563e7ec3 ("arm64: mm: support large block mapping when rodata=full") +Signed-off-by: Dev Jain +Reviewed-by: Ryan Roberts +Signed-off-by: Catalin Marinas +Signed-off-by: Sasha Levin +--- + arch/arm64/mm/pageattr.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c +index 5135f2d66958d..b4ea86cd3a719 100644 +--- a/arch/arm64/mm/pageattr.c ++++ b/arch/arm64/mm/pageattr.c +@@ -148,6 +148,7 @@ static int change_memory_common(unsigned long addr, int numpages, + unsigned long size = PAGE_SIZE * numpages; + unsigned long end = start + size; + struct vm_struct *area; ++ int ret; + int i; + + if (!PAGE_ALIGNED(addr)) { +@@ -185,8 +186,10 @@ static int change_memory_common(unsigned long addr, int numpages, + if (rodata_full && (pgprot_val(set_mask) == PTE_RDONLY || + pgprot_val(clear_mask) == PTE_RDONLY)) { + for (i = 0; i < area->nr_pages; i++) { +- __change_memory_common((u64)page_address(area->pages[i]), ++ ret = __change_memory_common((u64)page_address(area->pages[i]), + PAGE_SIZE, set_mask, clear_mask); ++ if (ret) ++ return ret; + } + } + +-- +2.51.0 + diff --git a/queue-6.18/arm64-tegra-add-pinctrl-definitions-for-pcie-ep-node.patch b/queue-6.18/arm64-tegra-add-pinctrl-definitions-for-pcie-ep-node.patch new file mode 100644 index 0000000000..ddb7ba368b --- /dev/null +++ b/queue-6.18/arm64-tegra-add-pinctrl-definitions-for-pcie-ep-node.patch @@ -0,0 +1,147 @@ +From b8da7c1990381b9c5c692fb9891557f5ec66fa58 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 16:22:54 +0200 +Subject: arm64: tegra: Add pinctrl definitions for pcie-ep nodes + +From: Niklas Cassel + +[ Upstream commit 21ef26d0e71f053e809926d45b86b0afbc3686bb ] + +When the PCIe controller is running in endpoint mode, the controller +initialization is triggered by a PERST# (PCIe reset) GPIO deassertion. + +The driver has configured an IRQ to trigger when the PERST# GPIO changes +state. Without the pinctrl definition, we do not get an IRQ when PERST# +is deasserted, so the PCIe controller never gets initialized. + +Add the missing definitions, so that the controller actually gets +initialized. + +Fixes: ec142c44b026 ("arm64: tegra: Add P2U and PCIe controller nodes to Tegra234 DT") +Fixes: 0580286d0d22 ("arm64: tegra: Add Tegra234 PCIe C4 EP definition") +Signed-off-by: Niklas Cassel +Reviewed-by: Manikanta Maddireddy +[treding@nvidia.com: add blank lines to separate blocks] +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/nvidia/tegra234.dtsi | 61 ++++++++++++++++++++++++ + 1 file changed, 61 insertions(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +index df034dbb82853..5657045c53d90 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + + / { + compatible = "nvidia,tegra234"; +@@ -127,6 +128,56 @@ gpio: gpio@2200000 { + pinmux: pinmux@2430000 { + compatible = "nvidia,tegra234-pinmux"; + reg = <0x0 0x2430000 0x0 0x19100>; ++ ++ pex_rst_c4_in_state: pinmux-pex-rst-c4-in { ++ pex_rst { ++ nvidia,pins = "pex_l4_rst_n_pl1"; ++ nvidia,function = "rsvd1"; ++ nvidia,pull = ; ++ nvidia,tristate = ; ++ nvidia,enable-input = ; ++ }; ++ }; ++ ++ pex_rst_c5_in_state: pinmux-pex-rst-c5-in { ++ pex_rst { ++ nvidia,pins = "pex_l5_rst_n_paf1"; ++ nvidia,function = "rsvd1"; ++ nvidia,pull = ; ++ nvidia,tristate = ; ++ nvidia,enable-input = ; ++ }; ++ }; ++ ++ pex_rst_c6_in_state: pinmux-pex-rst-c6-in { ++ pex_rst { ++ nvidia,pins = "pex_l6_rst_n_paf3"; ++ nvidia,function = "rsvd1"; ++ nvidia,pull = ; ++ nvidia,tristate = ; ++ nvidia,enable-input = ; ++ }; ++ }; ++ ++ pex_rst_c7_in_state: pinmux-pex-rst-c7-in { ++ pex_rst { ++ nvidia,pins = "pex_l7_rst_n_pag1"; ++ nvidia,function = "rsvd1"; ++ nvidia,pull = ; ++ nvidia,tristate = ; ++ nvidia,enable-input = ; ++ }; ++ }; ++ ++ pex_rst_c10_in_state: pinmux-pex-rst-c10-in { ++ pex_rst { ++ nvidia,pins = "pex_l10_rst_n_pag7"; ++ nvidia,function = "rsvd1"; ++ nvidia,pull = ; ++ nvidia,tristate = ; ++ nvidia,enable-input = ; ++ }; ++ }; + }; + + gpcdma: dma-controller@2600000 { +@@ -4630,6 +4681,8 @@ pcie-ep@140e0000 { + <&bpmp TEGRA234_RESET_PEX2_CORE_10>; + reset-names = "apb", "core"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pex_rst_c10_in_state>; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + +@@ -4881,6 +4934,8 @@ pcie-ep@14160000 { + <&bpmp TEGRA234_RESET_PEX0_CORE_4>; + reset-names = "apb", "core"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pex_rst_c4_in_state>; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + nvidia,bpmp = <&bpmp 4>; +@@ -5023,6 +5078,8 @@ pcie-ep@141a0000 { + <&bpmp TEGRA234_RESET_PEX1_CORE_5>; + reset-names = "apb", "core"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pex_rst_c5_in_state>; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + +@@ -5115,6 +5172,8 @@ pcie-ep@141c0000 { + <&bpmp TEGRA234_RESET_PEX1_CORE_6>; + reset-names = "apb", "core"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pex_rst_c6_in_state>; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + +@@ -5207,6 +5266,8 @@ pcie-ep@141e0000 { + <&bpmp TEGRA234_RESET_PEX2_CORE_7>; + reset-names = "apb", "core"; + ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pex_rst_c7_in_state>; + interrupts = ; /* controller interrupt */ + interrupt-names = "intr"; + +-- +2.51.0 + diff --git a/queue-6.18/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-6.18/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..ef504b0de4 --- /dev/null +++ b/queue-6.18/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From 4cd3cacb5833f240008c2e1eeb36025982d7d880 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 5d804860f7d8c..58db4906a01d5 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1421,7 +1421,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, +-- +2.51.0 + diff --git a/queue-6.18/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-6.18/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..071bb6e8f1 --- /dev/null +++ b/queue-6.18/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From 505d8e7062111bad2ab8e926e5f98fb957764bdf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index bf734c69c4e09..eb03cecdee281 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-6.18/asoc-nau8325-add-missing-build-config.patch b/queue-6.18/asoc-nau8325-add-missing-build-config.patch new file mode 100644 index 0000000000..9b0ca3668a --- /dev/null +++ b/queue-6.18/asoc-nau8325-add-missing-build-config.patch @@ -0,0 +1,70 @@ +From 8882387cee2aa69b2203425b72b5b481b65e2813 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:35 +0100 +Subject: ASoC: nau8325: add missing build config + +From: Jaroslav Kysela + +[ Upstream commit cd41d3420ef658b2ca902d7677536ec8e25b610a ] + +This configuration was missing from the initial commit. + +Found by Jiri Benc + +Fixes: c0a3873b9938 ("ASoC: nau8325: new driver") +Cc: Seven Lee +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-3-perex@perex.cz +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/Kconfig | 5 +++++ + sound/soc/codecs/Makefile | 2 ++ + 2 files changed, 7 insertions(+) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 160c07699a8b7..91ac99bc3edb2 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -170,6 +170,7 @@ config SND_SOC_ALL_CODECS + imply SND_SOC_MT6359 + imply SND_SOC_MT6660 + imply SND_SOC_NAU8315 ++ imply SND_SOC_NAU8325 + imply SND_SOC_NAU8540 + imply SND_SOC_NAU8810 + imply SND_SOC_NAU8821 +@@ -2715,6 +2716,10 @@ config SND_SOC_MT6660 + config SND_SOC_NAU8315 + tristate "Nuvoton Technology Corporation NAU8315 CODEC" + ++config SND_SOC_NAU8325 ++ tristate "Nuvoton Technology Corporation NAU8325 CODEC" ++ depends on I2C ++ + config SND_SOC_NAU8540 + tristate "Nuvoton Technology Corporation NAU85L40 CODEC" + depends on I2C +diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile +index bd95a7c911d5c..da4077463278e 100644 +--- a/sound/soc/codecs/Makefile ++++ b/sound/soc/codecs/Makefile +@@ -192,6 +192,7 @@ snd-soc-mt6359-y := mt6359.o + snd-soc-mt6359-accdet-y := mt6359-accdet.o + snd-soc-mt6660-y := mt6660.o + snd-soc-nau8315-y := nau8315.o ++snd-soc-nau8325-y := nau8325.o + snd-soc-nau8540-y := nau8540.o + snd-soc-nau8810-y := nau8810.o + snd-soc-nau8821-y := nau8821.o +@@ -618,6 +619,7 @@ obj-$(CONFIG_SND_SOC_MT6359) += snd-soc-mt6359.o + obj-$(CONFIG_SND_SOC_MT6359_ACCDET) += mt6359-accdet.o + obj-$(CONFIG_SND_SOC_MT6660) += snd-soc-mt6660.o + obj-$(CONFIG_SND_SOC_NAU8315) += snd-soc-nau8315.o ++obj-$(CONFIG_SND_SOC_NAU8325) += snd-soc-nau8325.o + obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o + obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o + obj-$(CONFIG_SND_SOC_NAU8821) += snd-soc-nau8821.o +-- +2.51.0 + diff --git a/queue-6.18/asoc-nau8325-use-simple-i2c-probe-function.patch b/queue-6.18/asoc-nau8325-use-simple-i2c-probe-function.patch new file mode 100644 index 0000000000..72cdb80368 --- /dev/null +++ b/queue-6.18/asoc-nau8325-use-simple-i2c-probe-function.patch @@ -0,0 +1,41 @@ +From 032203e5b08b5d5d0b153306ab1b7e255a746805 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:16:34 +0100 +Subject: ASoC: nau8325: use simple i2c probe function + +From: Jaroslav Kysela + +[ Upstream commit b4d072c98e47c562834f2a050ca98a1c709ef4f9 ] + +The i2c probe functions here don't use the id information provided in +their second argument, so the single-parameter i2c probe function +("probe_new") can be used instead. + +This avoids scanning the identifier tables during probes. + +Signed-off-by: Jaroslav Kysela +Link: https://patch.msgid.link/20251126091759.2490019-2-perex@perex.cz +Signed-off-by: Mark Brown +Stable-dep-of: cd41d3420ef6 ("ASoC: nau8325: add missing build config") +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/nau8325.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/nau8325.c b/sound/soc/codecs/nau8325.c +index 2266f320a8f22..5b3115b0a7e58 100644 +--- a/sound/soc/codecs/nau8325.c ++++ b/sound/soc/codecs/nau8325.c +@@ -829,8 +829,7 @@ static int nau8325_read_device_properties(struct device *dev, + return 0; + } + +-static int nau8325_i2c_probe(struct i2c_client *i2c, +- const struct i2c_device_id *id) ++static int nau8325_i2c_probe(struct i2c_client *i2c) + { + struct device *dev = &i2c->dev; + struct nau8325 *nau8325 = dev_get_platdata(dev); +-- +2.51.0 + diff --git a/queue-6.18/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch b/queue-6.18/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch new file mode 100644 index 0000000000..5af40246d1 --- /dev/null +++ b/queue-6.18/asoc-sdca-fix-missing-dash-in-hide-disco-property.patch @@ -0,0 +1,42 @@ +From 8e958817f4f4ad45638c8d9cc03534cea92fba75 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:30:11 +0000 +Subject: ASoC: SDCA: Fix missing dash in HIDE DisCo property + +From: Charles Keepax + +[ Upstream commit 3508311f2e1c872b645f13c6fd52840418089d41 ] + +The property name is "mipi-sdca-RxUMP-ownership-transition-max-delay", +with a dash between max and delay. Add the missing dash. + +Fixes: 13ef21dffe76 ("ASoC: SDCA: add support for HIDE entity properties and HID descriptor/report") +Tested-by: Bard Liao +Reviewed-by: Maciej Strozek +Reviewed-by: Peter Ujfalusi +Tested-by: Richard Fitzgerald +Signed-off-by: Charles Keepax +Link: https://patch.msgid.link/20251120153023.2105663-3-ckeepax@opensource.cirrus.com +Reviewed-by: Vinod Koul +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/sdca/sdca_functions.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/sdca/sdca_functions.c b/sound/soc/sdca/sdca_functions.c +index 0ccb6775f4de3..19b12564f822e 100644 +--- a/sound/soc/sdca/sdca_functions.c ++++ b/sound/soc/sdca/sdca_functions.c +@@ -1263,7 +1263,7 @@ find_sdca_entity_hide(struct device *dev, struct fwnode_handle *function_node, + unsigned char *report_desc = NULL; + + ret = fwnode_property_read_u32(entity_node, +- "mipi-sdca-RxUMP-ownership-transition-maxdelay", &delay); ++ "mipi-sdca-RxUMP-ownership-transition-max-delay", &delay); + if (!ret) + hide->max_delay = delay; + +-- +2.51.0 + diff --git a/queue-6.18/asoc-tas2781-correct-the-wrong-chip-id-for-reset-var.patch b/queue-6.18/asoc-tas2781-correct-the-wrong-chip-id-for-reset-var.patch new file mode 100644 index 0000000000..c4fecd2a12 --- /dev/null +++ b/queue-6.18/asoc-tas2781-correct-the-wrong-chip-id-for-reset-var.patch @@ -0,0 +1,38 @@ +From 1c73e22cd5521d30efbaf6d7e665fbc2b5bfa257 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 11:15:42 +0800 +Subject: ASoC: tas2781: Correct the wrong chip ID for reset variable check + +From: Baojun Xu + +[ Upstream commit 34b78ddd78428e66a7f08f71763258723eae2306 ] + +The new variable of reset was added for TAS58XX on TAS5825 first. +And TAS5802/5815... was added later, so this reset variable check +should be changed to lowest chip of TAS58XX. + +Fixes: 53a3c6e22283 ("ASoC: tas2781: Support more newly-released amplifiers tas58xx in the driver") +Signed-off-by: Baojun Xu +Link: https://patch.msgid.link/20251124031542.2793-1-baojun.xu@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2781-comlib-i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2781-comlib-i2c.c b/sound/soc/codecs/tas2781-comlib-i2c.c +index b3fd7350143bd..e24d56a14cfda 100644 +--- a/sound/soc/codecs/tas2781-comlib-i2c.c ++++ b/sound/soc/codecs/tas2781-comlib-i2c.c +@@ -320,7 +320,7 @@ void tasdevice_reset(struct tasdevice_priv *tas_dev) + for (i = 0; i < tas_dev->ndev; i++) { + ret = tasdevice_dev_write(tas_dev, i, + TASDEVICE_REG_SWRESET, +- tas_dev->chip_id >= TAS5825 ? ++ tas_dev->chip_id >= TAS5802 ? + TAS5825_REG_SWRESET_RESET : + TASDEVICE_REG_SWRESET_RESET); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-6.18/asoc-tas2781-correct-the-wrong-period.patch b/queue-6.18/asoc-tas2781-correct-the-wrong-period.patch new file mode 100644 index 0000000000..b81ccb27fe --- /dev/null +++ b/queue-6.18/asoc-tas2781-correct-the-wrong-period.patch @@ -0,0 +1,37 @@ +From d9190609e874298d63f30da87447d1d28104335d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 07:44:27 +0800 +Subject: ASoC: tas2781: correct the wrong period + +From: Shenghao Ding + +[ Upstream commit 950167a99dfd27eeaf177092908c598a31c79a7e ] + +A wrong preiod at the end of the sentence was reported by one of my +customers. Their thorough code review is greatly appreciated. + +Fixes: 49e2e353fb0d ("ASoC: tas2781: Add Calibration Kcontrols for Chromebook") +Signed-off-by: Shenghao Ding +Link: https://patch.msgid.link/20251121234427.402-1-shenghao-ding@ti.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/codecs/tas2781-i2c.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/tas2781-i2c.c b/sound/soc/codecs/tas2781-i2c.c +index 8f37aa00e62ee..a3b4d2c3b4789 100644 +--- a/sound/soc/codecs/tas2781-i2c.c ++++ b/sound/soc/codecs/tas2781-i2c.c +@@ -1391,7 +1391,7 @@ static int tasdevice_create_cali_ctrls(struct tasdevice_priv *priv) + + /* + * Alloc kcontrol via devm_kzalloc(), which don't manually +- * free the kcontrol。 ++ * free the kcontrol. + */ + cali_ctrls = devm_kcalloc(priv->dev, nctrls, + sizeof(cali_ctrls[0]), GFP_KERNEL); +-- +2.51.0 + diff --git a/queue-6.18/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-6.18/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..8d7800272b --- /dev/null +++ b/queue-6.18/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 1421c8bf1bcec17d6848ff4831c986e010396f17 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index efc5e380669ae..f7ab9b3607313 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -210,6 +210,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-6.18/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-6.18/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..8384e23a6b --- /dev/null +++ b/queue-6.18/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From 39e10b5ad496235c783aefe7f4bae19d5ba15629 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-6.18/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch b/queue-6.18/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch new file mode 100644 index 0000000000..0664dd0957 --- /dev/null +++ b/queue-6.18/block-blk-throttle-fix-throttle-slice-time-for-ssds.patch @@ -0,0 +1,73 @@ +From 47e6adb52e17b279be58304e521c6b33b9e696b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:54:32 -0800 +Subject: block/blk-throttle: Fix throttle slice time for SSDs + +From: Guenter Roeck + +[ Upstream commit f76581f9f1d29e32e120b0242974ba266e79de58 ] + +Commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD") +introduced device type specific throttle slices if BLK_DEV_THROTTLING_LOW +was enabled. Commit bf20ab538c81 ("blk-throttle: remove +CONFIG_BLK_DEV_THROTTLING_LOW") removed support for BLK_DEV_THROTTLING_LOW, +but left the device type specific throttle slices in place. This +effectively changed throttling behavior on systems with SSD which now use +a different and non-configurable slice time compared to non-SSD devices. +Practical impact is that throughput tests with low configured throttle +values (65536 bps) experience less than expected throughput on SSDs, +presumably due to rounding errors associated with the small throttle slice +time used for those devices. The same tests pass when setting the throttle +values to 65536 * 4 = 262144 bps. + +The original code sets the throttle slice time to DFL_THROTL_SLICE_HD if +CONFIG_BLK_DEV_THROTTLING_LOW is disabled. Restore that code to fix the +problem. With that, DFL_THROTL_SLICE_SSD is no longer necessary. Revert to +the original code and re-introduce DFL_THROTL_SLICE to replace both +DFL_THROTL_SLICE_HD and DFL_THROTL_SLICE_SSD. This effectively reverts +commit d61fcfa4bb18 ("blk-throttle: choose a small throtl_slice for SSD"). + +While at it, also remove MAX_THROTL_SLICE since it is not used anymore. + +Fixes: bf20ab538c81 ("blk-throttle: remove CONFIG_BLK_DEV_THROTTLING_LOW") +Cc: Yu Kuai +Cc: Tejun Heo +Signed-off-by: Guenter Roeck +Signed-off-by: Khazhismel Kumykov +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-throttle.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/block/blk-throttle.c b/block/blk-throttle.c +index 2c5b64b1a724a..c19d052a8f2f1 100644 +--- a/block/blk-throttle.c ++++ b/block/blk-throttle.c +@@ -22,9 +22,7 @@ + #define THROTL_QUANTUM 32 + + /* Throttling is performed over a slice and after that slice is renewed */ +-#define DFL_THROTL_SLICE_HD (HZ / 10) +-#define DFL_THROTL_SLICE_SSD (HZ / 50) +-#define MAX_THROTL_SLICE (HZ) ++#define DFL_THROTL_SLICE (HZ / 10) + + /* A workqueue to queue throttle related work */ + static struct workqueue_struct *kthrotld_workqueue; +@@ -1341,10 +1339,7 @@ static int blk_throtl_init(struct gendisk *disk) + goto out; + } + +- if (blk_queue_nonrot(q)) +- td->throtl_slice = DFL_THROTL_SLICE_SSD; +- else +- td->throtl_slice = DFL_THROTL_SLICE_HD; ++ td->throtl_slice = DFL_THROTL_SLICE; + td->track_bio_latency = !queue_is_mq(q); + if (!td->track_bio_latency) + blk_stat_enable_accounting(q); +-- +2.51.0 + diff --git a/queue-6.18/block-mq-deadline-introduce-dd_start_request.patch b/queue-6.18/block-mq-deadline-introduce-dd_start_request.patch new file mode 100644 index 0000000000..5a4943ae27 --- /dev/null +++ b/queue-6.18/block-mq-deadline-introduce-dd_start_request.patch @@ -0,0 +1,74 @@ +From 8463cb259bb04006d0808f91762b9efb93d3314d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:02 -0700 +Subject: block/mq-deadline: Introduce dd_start_request() + +From: Bart Van Assche + +[ Upstream commit 93a358af59c6e8ab00b57cfdb1c437516a4948ca ] + +Prepare for adding a second caller of this function. No functionality +has been changed. + +Cc: Damien Le Moal +Cc: Yu Kuai +Cc: chengkaitao +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moal +Signed-off-by: Jens Axboe +Stable-dep-of: d60055cf5270 ("block/mq-deadline: Switch back to a single dispatch list") +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 3e741d33142d3..647a45f6d9352 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -306,6 +306,19 @@ static bool started_after(struct deadline_data *dd, struct request *rq, + return time_after(start_time, latest_start); + } + ++static struct request *dd_start_request(struct deadline_data *dd, ++ enum dd_data_dir data_dir, ++ struct request *rq) ++{ ++ u8 ioprio_class = dd_rq_ioclass(rq); ++ enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; ++ ++ dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); ++ dd->per_prio[prio].stats.dispatched++; ++ rq->rq_flags |= RQF_STARTED; ++ return rq; ++} ++ + /* + * deadline_dispatch_requests selects the best request according to + * read/write expire, fifo_batch, etc and with a start time <= @latest_start. +@@ -316,8 +329,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + { + struct request *rq, *next_rq; + enum dd_data_dir data_dir; +- enum dd_prio prio; +- u8 ioprio_class; + + lockdep_assert_held(&dd->lock); + +@@ -411,12 +422,7 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + dd->batching++; + deadline_move_request(dd, per_prio, rq); + done: +- ioprio_class = dd_rq_ioclass(rq); +- prio = ioprio_class_to_prio[ioprio_class]; +- dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); +- dd->per_prio[prio].stats.dispatched++; +- rq->rq_flags |= RQF_STARTED; +- return rq; ++ return dd_start_request(dd, data_dir, rq); + } + + /* +-- +2.51.0 + diff --git a/queue-6.18/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch b/queue-6.18/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch new file mode 100644 index 0000000000..05f778667f --- /dev/null +++ b/queue-6.18/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch @@ -0,0 +1,227 @@ +From 14997cb851f7ecb26a1a77245738bde99652334d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:03 -0700 +Subject: block/mq-deadline: Switch back to a single dispatch list + +From: Bart Van Assche + +[ Upstream commit d60055cf52703a705b86fb25b9b7931ec7ee399c ] + +Commit c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +modified the behavior of request flag BLK_MQ_INSERT_AT_HEAD from +dispatching a request before other requests into dispatching a request +before other requests with the same I/O priority. This is not correct since +BLK_MQ_INSERT_AT_HEAD is used when requeuing requests and also when a flush +request is inserted. Both types of requests should be dispatched as soon +as possible. Hence, make the mq-deadline I/O scheduler again ignore the I/O +priority for BLK_MQ_INSERT_AT_HEAD requests. + +Cc: Damien Le Moal +Cc: Yu Kuai +Reported-by: chengkaitao +Closes: https://lore.kernel.org/linux-block/20251009155253.14611-1-pilgrimtao@gmail.com/ +Fixes: c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moalv +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 107 +++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 60 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 647a45f6d9352..3e3719093aec7 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -71,7 +71,6 @@ struct io_stats_per_prio { + * present on both sort_list[] and fifo_list[]. + */ + struct dd_per_prio { +- struct list_head dispatch; + struct rb_root sort_list[DD_DIR_COUNT]; + struct list_head fifo_list[DD_DIR_COUNT]; + /* Position of the most recently dispatched request. */ +@@ -84,6 +83,7 @@ struct deadline_data { + * run time data + */ + ++ struct list_head dispatch; + struct dd_per_prio per_prio[DD_PRIO_COUNT]; + + /* Data direction of latest dispatched request. */ +@@ -332,16 +332,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + + lockdep_assert_held(&dd->lock); + +- if (!list_empty(&per_prio->dispatch)) { +- rq = list_first_entry(&per_prio->dispatch, struct request, +- queuelist); +- if (started_after(dd, rq, latest_start)) +- return NULL; +- list_del_init(&rq->queuelist); +- data_dir = rq_data_dir(rq); +- goto done; +- } +- + /* + * batches are currently reads XOR writes + */ +@@ -421,7 +411,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + */ + dd->batching++; + deadline_move_request(dd, per_prio, rq); +-done: + return dd_start_request(dd, data_dir, rq); + } + +@@ -469,6 +458,14 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) + enum dd_prio prio; + + spin_lock(&dd->lock); ++ ++ if (!list_empty(&dd->dispatch)) { ++ rq = list_first_entry(&dd->dispatch, struct request, queuelist); ++ list_del_init(&rq->queuelist); ++ dd_start_request(dd, rq_data_dir(rq), rq); ++ goto unlock; ++ } ++ + rq = dd_dispatch_prio_aged_requests(dd, now); + if (rq) + goto unlock; +@@ -557,10 +554,10 @@ static int dd_init_sched(struct request_queue *q, struct elevator_queue *eq) + + eq->elevator_data = dd; + ++ INIT_LIST_HEAD(&dd->dispatch); + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + +- INIT_LIST_HEAD(&per_prio->dispatch); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_READ]); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_WRITE]); + per_prio->sort_list[DD_READ] = RB_ROOT; +@@ -664,7 +661,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + trace_block_rq_insert(rq); + + if (flags & BLK_MQ_INSERT_AT_HEAD) { +- list_add(&rq->queuelist, &per_prio->dispatch); ++ list_add(&rq->queuelist, &dd->dispatch); + rq->fifo_time = jiffies; + } else { + deadline_add_rq_rb(per_prio, rq); +@@ -731,8 +728,7 @@ static void dd_finish_request(struct request *rq) + + static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) + { +- return !list_empty_careful(&per_prio->dispatch) || +- !list_empty_careful(&per_prio->fifo_list[DD_READ]) || ++ return !list_empty_careful(&per_prio->fifo_list[DD_READ]) || + !list_empty_careful(&per_prio->fifo_list[DD_WRITE]); + } + +@@ -741,6 +737,9 @@ static bool dd_has_work(struct blk_mq_hw_ctx *hctx) + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + enum dd_prio prio; + ++ if (!list_empty_careful(&dd->dispatch)) ++ return true; ++ + for (prio = 0; prio <= DD_PRIO_MAX; prio++) + if (dd_has_work_for_prio(&dd->per_prio[prio])) + return true; +@@ -949,49 +948,39 @@ static int dd_owned_by_driver_show(void *data, struct seq_file *m) + return 0; + } + +-#define DEADLINE_DISPATCH_ATTR(prio) \ +-static void *deadline_dispatch##prio##_start(struct seq_file *m, \ +- loff_t *pos) \ +- __acquires(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- spin_lock(&dd->lock); \ +- return seq_list_start(&per_prio->dispatch, *pos); \ +-} \ +- \ +-static void *deadline_dispatch##prio##_next(struct seq_file *m, \ +- void *v, loff_t *pos) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- return seq_list_next(v, &per_prio->dispatch, pos); \ +-} \ +- \ +-static void deadline_dispatch##prio##_stop(struct seq_file *m, void *v) \ +- __releases(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- \ +- spin_unlock(&dd->lock); \ +-} \ +- \ +-static const struct seq_operations deadline_dispatch##prio##_seq_ops = { \ +- .start = deadline_dispatch##prio##_start, \ +- .next = deadline_dispatch##prio##_next, \ +- .stop = deadline_dispatch##prio##_stop, \ +- .show = blk_mq_debugfs_rq_show, \ ++static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) ++ __acquires(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_lock(&dd->lock); ++ return seq_list_start(&dd->dispatch, *pos); + } + +-DEADLINE_DISPATCH_ATTR(0); +-DEADLINE_DISPATCH_ATTR(1); +-DEADLINE_DISPATCH_ATTR(2); +-#undef DEADLINE_DISPATCH_ATTR ++static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ return seq_list_next(v, &dd->dispatch, pos); ++} ++ ++static void deadline_dispatch_stop(struct seq_file *m, void *v) ++ __releases(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_unlock(&dd->lock); ++} ++ ++static const struct seq_operations deadline_dispatch_seq_ops = { ++ .start = deadline_dispatch_start, ++ .next = deadline_dispatch_next, ++ .stop = deadline_dispatch_stop, ++ .show = blk_mq_debugfs_rq_show, ++}; + + #define DEADLINE_QUEUE_DDIR_ATTRS(name) \ + {#name "_fifo_list", 0400, \ +@@ -1014,9 +1003,7 @@ static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { + {"batching", 0400, deadline_batching_show}, + {"starved", 0400, deadline_starved_show}, + {"async_depth", 0400, dd_async_depth_show}, +- {"dispatch0", 0400, .seq_ops = &deadline_dispatch0_seq_ops}, +- {"dispatch1", 0400, .seq_ops = &deadline_dispatch1_seq_ops}, +- {"dispatch2", 0400, .seq_ops = &deadline_dispatch2_seq_ops}, ++ {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, + {"owned_by_driver", 0400, dd_owned_by_driver_show}, + {"queued", 0400, dd_queued_show}, + {}, +-- +2.51.0 + diff --git a/queue-6.18/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch b/queue-6.18/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch new file mode 100644 index 0000000000..5e23bfb9fd --- /dev/null +++ b/queue-6.18/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch @@ -0,0 +1,69 @@ +From 27a25f00b3d411ca22c0b149916262683a63e95d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:23:30 -0800 +Subject: bpf: Check skb->transport_header is set in bpf_skb_check_mtu + +From: Martin KaFai Lau + +[ Upstream commit d946f3c98328171fa50ddb908593cf833587f725 ] + +The bpf_skb_check_mtu helper needs to use skb->transport_header when +the BPF_MTU_CHK_SEGS flag is used: + + bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) + +The transport_header is not always set. There is a WARN_ON_ONCE +report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + +bpf_prog_test_run is used: + +WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 + skb_gso_validate_network_len + bpf_skb_check_mtu + bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch + bpf_test_run + bpf_prog_test_run_skb + +For a normal ingress skb (not test_run), skb_reset_transport_header +is performed but there is plan to avoid setting it as described in +commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). + +This patch fixes the bpf helper by checking +skb_transport_header_was_set(). The check is done just before +skb->transport_header is used, to avoid breaking the existing bpf prog. +The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. + +Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") +Cc: Jesper Dangaard Brouer +Reported-by: Kaiyan Mei +Reported-by: Yinhao Hu +Signed-off-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 1efec0d70d783..df6ce85e48dcd 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -6429,9 +6429,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, + */ + if (skb_is_gso(skb)) { + ret = BPF_MTU_CHK_RET_SUCCESS; +- if (flags & BPF_MTU_CHK_SEGS && +- !skb_gso_validate_network_len(skb, mtu)) +- ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ if (flags & BPF_MTU_CHK_SEGS) { ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ if (!skb_gso_validate_network_len(skb, mtu)) ++ ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ } + } + out: + *mtu_len = mtu; +-- +2.51.0 + diff --git a/queue-6.18/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch b/queue-6.18/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch new file mode 100644 index 0000000000..69d643b1d4 --- /dev/null +++ b/queue-6.18/bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch @@ -0,0 +1,94 @@ +From cbd4578d162e45a4ed951ae83ab398b3a6f9aafa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 17:27:02 +0000 +Subject: bpf: Cleanup unused func args in rqspinlock implementation + +From: Siddharth Chintamaneni + +[ Upstream commit 56b4d162392dda2365fbc1f482184a24b489d07d ] + +cleanup unused function args in check_deadlock* functions. + +Fixes: 31158ad02ddb ("rqspinlock: Add deadlock detection and recovery") +Signed-off-by: Siddharth Chintamaneni +Reviewed-by: Eduard Zingerman +Acked-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251001172702.122838-1-sidchintamaneni@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/rqspinlock.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index a00561b1d3e51..21be48108e962 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -89,15 +89,14 @@ struct rqspinlock_timeout { + DEFINE_PER_CPU_ALIGNED(struct rqspinlock_held, rqspinlock_held_locks); + EXPORT_SYMBOL_GPL(rqspinlock_held_locks); + +-static bool is_lock_released(rqspinlock_t *lock, u32 mask, struct rqspinlock_timeout *ts) ++static bool is_lock_released(rqspinlock_t *lock, u32 mask) + { + if (!(atomic_read_acquire(&lock->val) & (mask))) + return true; + return false; + } + +-static noinline int check_deadlock_AA(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock_AA(rqspinlock_t *lock) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + int cnt = min(RES_NR_HELD, rqh->cnt); +@@ -118,8 +117,7 @@ static noinline int check_deadlock_AA(rqspinlock_t *lock, u32 mask, + * more locks, which reduce to ABBA). This is not exhaustive, and we rely on + * timeouts as the final line of defense. + */ +-static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + int rqh_cnt = min(RES_NR_HELD, rqh->cnt); +@@ -142,7 +140,7 @@ static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, + * Let's ensure to break out of this loop if the lock is available for + * us to potentially acquire. + */ +- if (is_lock_released(lock, mask, ts)) ++ if (is_lock_released(lock, mask)) + return 0; + + /* +@@ -198,15 +196,14 @@ static noinline int check_deadlock_ABBA(rqspinlock_t *lock, u32 mask, + return 0; + } + +-static noinline int check_deadlock(rqspinlock_t *lock, u32 mask, +- struct rqspinlock_timeout *ts) ++static noinline int check_deadlock(rqspinlock_t *lock, u32 mask) + { + int ret; + +- ret = check_deadlock_AA(lock, mask, ts); ++ ret = check_deadlock_AA(lock); + if (ret) + return ret; +- ret = check_deadlock_ABBA(lock, mask, ts); ++ ret = check_deadlock_ABBA(lock, mask); + if (ret) + return ret; + +@@ -234,7 +231,7 @@ static noinline int check_timeout(rqspinlock_t *lock, u32 mask, + */ + if (prev + NSEC_PER_MSEC < time) { + ts->cur = time; +- return check_deadlock(lock, mask, ts); ++ return check_deadlock(lock, mask); + } + + return 0; +-- +2.51.0 + diff --git a/queue-6.18/bpf-do-not-let-bpf-test-infra-emit-invalid-gso-types.patch b/queue-6.18/bpf-do-not-let-bpf-test-infra-emit-invalid-gso-types.patch new file mode 100644 index 0000000000..1f23072d2c --- /dev/null +++ b/queue-6.18/bpf-do-not-let-bpf-test-infra-emit-invalid-gso-types.patch @@ -0,0 +1,84 @@ +From 42611e7fafa10c38da1d9e087ddd9e3a170bc52b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 09:54:41 +0200 +Subject: bpf: Do not let BPF test infra emit invalid GSO types to stack + +From: Daniel Borkmann + +[ Upstream commit 04a899573fb87273a656f178b5f920c505f68875 ] + +Yinhao et al. reported that their fuzzer tool was able to trigger a +skb_warn_bad_offload() from netif_skb_features() -> gso_features_check(). +When a BPF program - triggered via BPF test infra - pushes the packet +to the loopback device via bpf_clone_redirect() then mentioned offload +warning can be seen. GSO-related features are then rightfully disabled. + +We get into this situation due to convert___skb_to_skb() setting +gso_segs and gso_size but not gso_type. Technically, it makes sense +that this warning triggers since the GSO properties are malformed due +to the gso_type. Potentially, the gso_type could be marked non-trustworthy +through setting it at least to SKB_GSO_DODGY without any other specific +assumptions, but that also feels wrong given we should not go further +into the GSO engine in the first place. + +The checks were added in 121d57af308d ("gso: validate gso_type in GSO +handlers") because there were malicious (syzbot) senders that combine +a protocol with a non-matching gso_type. If we would want to drop such +packets, gso_features_check() currently only returns feature flags via +netif_skb_features(), so one location for potentially dropping such skbs +could be validate_xmit_unreadable_skb(), but then otoh it would be +an additional check in the fast-path for a very corner case. Given +bpf_clone_redirect() is the only place where BPF test infra could emit +such packets, lets reject them right there. + +Fixes: 850a88cc4096 ("bpf: Expose __sk_buff wire_len/gso_segs to BPF_PROG_TEST_RUN") +Fixes: cf62089b0edd ("bpf: Add gso_size to __sk_buff") +Reported-by: Yinhao Hu +Reported-by: Kaiyan Mei +Reported-by: Dongliang Mu +Signed-off-by: Daniel Borkmann +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20251020075441.127980-1-daniel@iogearbox.net +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 5 +++++ + net/core/filter.c | 7 +++++++ + 2 files changed, 12 insertions(+) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 8b7d0b90fea76..55a79337ac51f 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -939,6 +939,11 @@ static int convert___skb_to_skb(struct sk_buff *skb, struct __sk_buff *__skb) + + if (__skb->gso_segs > GSO_MAX_SEGS) + return -EINVAL; ++ ++ /* Currently GSO type is zero/unset. If this gets extended with ++ * a small list of accepted GSO types in future, the filter for ++ * an unset GSO type in bpf_clone_redirect() can be lifted. ++ */ + skb_shinfo(skb)->gso_segs = __skb->gso_segs; + skb_shinfo(skb)->gso_size = __skb->gso_size; + skb_shinfo(skb)->hwtstamps.hwtstamp = __skb->hwtstamp; +diff --git a/net/core/filter.c b/net/core/filter.c +index fa06c5a08e22f..1efec0d70d783 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -2458,6 +2458,13 @@ BPF_CALL_3(bpf_clone_redirect, struct sk_buff *, skb, u32, ifindex, u64, flags) + if (unlikely(flags & (~(BPF_F_INGRESS) | BPF_F_REDIRECT_INTERNAL))) + return -EINVAL; + ++ /* BPF test infra's convert___skb_to_skb() can create type-less ++ * GSO packets. gso_features_check() will detect this as a bad ++ * offload. However, lets not leak them out in the first place. ++ */ ++ if (unlikely(skb_is_gso(skb) && !skb_shinfo(skb)->gso_type)) ++ return -EBADMSG; ++ + dev = dev_get_by_index_rcu(dev_net(skb->dev), ifindex); + if (unlikely(!dev)) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-exclusive-map-memory-leak.patch b/queue-6.18/bpf-fix-exclusive-map-memory-leak.patch new file mode 100644 index 0000000000..30c41c367d --- /dev/null +++ b/queue-6.18/bpf-fix-exclusive-map-memory-leak.patch @@ -0,0 +1,49 @@ +From 957ca1dfc475c3e479176e5c2ff008ed9499931e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 16 Nov 2025 22:58:13 +0800 +Subject: bpf: Fix exclusive map memory leak + +From: Edward Adam Davis + +[ Upstream commit 688b745401ab16e2e1a3b504863f0a45fd345638 ] + +When excl_prog_hash is 0 and excl_prog_hash_size is non-zero, the map also +needs to be freed. Otherwise, the map memory will not be reclaimed, just +like the memory leak problem reported by syzbot [1]. + +syzbot reported: +BUG: memory leak + backtrace (crc 7b9fb9b4): + map_create+0x322/0x11e0 kernel/bpf/syscall.c:1512 + __sys_bpf+0x3556/0x3610 kernel/bpf/syscall.c:6131 + +Fixes: baefdbdf6812 ("bpf: Implement exclusive map creation") +Reported-by: syzbot+cf08c551fecea9fd1320@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=cf08c551fecea9fd1320 +Tested-by: syzbot+cf08c551fecea9fd1320@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/tencent_3F226F882CE56DCC94ACE90EED1ECCFC780A@qq.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/syscall.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 15f9afdbfc275..df219e7259099 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -1585,7 +1585,8 @@ static int map_create(union bpf_attr *attr, bpfptr_t uattr) + goto free_map; + } + } else if (attr->excl_prog_hash_size) { +- return -EINVAL; ++ err = -EINVAL; ++ goto free_map; + } + + err = security_bpf_map_create(map, attr, token, uattr.is_kernel); +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-handling-maps-with-no-btf-and-non-constant-o.patch b/queue-6.18/bpf-fix-handling-maps-with-no-btf-and-non-constant-o.patch new file mode 100644 index 0000000000..2d6ef1a02f --- /dev/null +++ b/queue-6.18/bpf-fix-handling-maps-with-no-btf-and-non-constant-o.patch @@ -0,0 +1,67 @@ +From d3beb738094e17e5598c1d377977947d6e85a67d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 17:46:04 +0100 +Subject: bpf: Fix handling maps with no BTF and non-constant offsets for the + bpf_wq + +From: Mykyta Yatsenko + +[ Upstream commit 5f8d41172931a92339c5cce81a3142065fa56e45 ] + +Fix handling maps with no BTF and non-constant offsets for the bpf_wq. + +This de-duplicates logic with other internal structs (task_work, timer), +keeps error reporting consistent, and makes future changes to the layout +handling centralized. + +Fixes: d940c9b94d7e ("bpf: add support for KF_ARG_PTR_TO_WORKQUEUE") +Signed-off-by: Mykyta Yatsenko +Acked-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20251010164606.147298-1-mykyta.yatsenko5@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 460107b0449fe..52c01c011c6fb 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -8479,6 +8479,9 @@ static int check_map_field_pointer(struct bpf_verifier_env *env, u32 regno, + case BPF_TASK_WORK: + field_off = map->record->task_work_off; + break; ++ case BPF_WORKQUEUE: ++ field_off = map->record->wq_off; ++ break; + default: + verifier_bug(env, "unsupported BTF field type: %s\n", struct_name); + return -EINVAL; +@@ -8520,13 +8523,17 @@ static int process_wq_func(struct bpf_verifier_env *env, int regno, + { + struct bpf_reg_state *regs = cur_regs(env), *reg = ®s[regno]; + struct bpf_map *map = reg->map_ptr; +- u64 val = reg->var_off.value; ++ int err; + +- if (map->record->wq_off != val + reg->off) { +- verbose(env, "off %lld doesn't point to 'struct bpf_wq' that is at %d\n", +- val + reg->off, map->record->wq_off); +- return -EINVAL; ++ err = check_map_field_pointer(env, regno, BPF_WORKQUEUE); ++ if (err) ++ return err; ++ ++ if (meta->map.ptr) { ++ verifier_bug(env, "Two map pointers in a bpf_wq helper"); ++ return -EFAULT; + } ++ + meta->map.uid = reg->map_uid; + meta->map.ptr = map; + return 0; +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-invalid-prog-stats-access-when-update_effect.patch b/queue-6.18/bpf-fix-invalid-prog-stats-access-when-update_effect.patch new file mode 100644 index 0000000000..db3f8af3b9 --- /dev/null +++ b/queue-6.18/bpf-fix-invalid-prog-stats-access-when-update_effect.patch @@ -0,0 +1,91 @@ +From ffbf81a7e8a33f320c1b90e7dc670b27f265569b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:23:43 +0000 +Subject: bpf: Fix invalid prog->stats access when update_effective_progs fails + +From: Pu Lehui + +[ Upstream commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc ] + +Syzkaller triggers an invalid memory access issue following fault +injection in update_effective_progs. The issue can be described as +follows: + +__cgroup_bpf_detach + update_effective_progs + compute_effective_progs + bpf_prog_array_alloc <-- fault inject + purge_effective_progs + /* change to dummy_bpf_prog */ + array->items[index] = &dummy_bpf_prog.prog + +---softirq start--- +__do_softirq + ... + __cgroup_bpf_run_filter_skb + __bpf_prog_run_save_cb + bpf_prog_run + stats = this_cpu_ptr(prog->stats) + /* invalid memory access */ + flags = u64_stats_update_begin_irqsave(&stats->syncp) +---softirq end--- + + static_branch_dec(&cgroup_bpf_enabled_key[atype]) + +The reason is that fault injection caused update_effective_progs to fail +and then changed the original prog into dummy_bpf_prog.prog in +purge_effective_progs. Then a softirq came, and accessing the members of +dummy_bpf_prog.prog in the softirq triggers invalid mem access. + +To fix it, skip updating stats when stats is NULL. + +Fixes: 492ecee892c2 ("bpf: enable program stats") +Signed-off-by: Pu Lehui +Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 12 +++++++----- + kernel/bpf/syscall.c | 3 +++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index 973233b82dc1f..569de3b14279a 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -712,11 +712,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; +- stats = this_cpu_ptr(prog->stats); +- flags = u64_stats_update_begin_irqsave(&stats->syncp); +- u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, duration); +- u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ if (likely(prog->stats)) { ++ stats = this_cpu_ptr(prog->stats); ++ flags = u64_stats_update_begin_irqsave(&stats->syncp); ++ u64_stats_inc(&stats->cnt); ++ u64_stats_add(&stats->nsecs, duration); ++ u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ } + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 8a129746bd6cc..15f9afdbfc275 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2462,6 +2462,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) + struct bpf_prog_stats *stats; + unsigned int flags; + ++ if (unlikely(!prog->stats)) ++ return; ++ + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-sleepable-context-for-async-callbacks.patch b/queue-6.18/bpf-fix-sleepable-context-for-async-callbacks.patch new file mode 100644 index 0000000000..5ca7df860d --- /dev/null +++ b/queue-6.18/bpf-fix-sleepable-context-for-async-callbacks.patch @@ -0,0 +1,199 @@ +From f6e18c7f7411a74cb829bda26edf86d89f626e49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 22:03:47 +0000 +Subject: bpf: Fix sleepable context for async callbacks + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 469d638d1520a9332cd0d034690e75e845610a51 ] + +Fix the BPF verifier to correctly determine the sleepable context of +async callbacks based on the async primitive type rather than the arming +program's context. + +The bug is in in_sleepable() which uses OR logic to check if the current +execution context is sleepable. When a sleepable program arms a timer +callback, the callback's state correctly has in_sleepable=false, but +in_sleepable() would still return true due to env->prog->sleepable being +true. This incorrectly allows sleepable helpers like +bpf_copy_from_user() inside timer callbacks when armed from sleepable +programs, even though timer callbacks always execute in non-sleepable +context. + +Fix in_sleepable() to rely solely on env->cur_state->in_sleepable, and +initialize state->in_sleepable to env->prog->sleepable in +do_check_common() for the main program entry. This ensures the sleepable +context is properly tracked per verification state rather than being +overridden by the program's sleepability. + +The env->cur_state NULL check in in_sleepable() was only needed for +do_misc_fixups() which runs after verification when env->cur_state is +set to NULL. Update do_misc_fixups() to use env->prog->sleepable +directly for the storage_get_function check, and remove the redundant +NULL check from in_sleepable(). + +Introduce is_async_cb_sleepable() helper to explicitly determine async +callback sleepability based on the primitive type: + - bpf_timer callbacks are never sleepable + - bpf_wq and bpf_task_work callbacks are always sleepable + +Add verifier_bug() check to catch unhandled async callback types, +ensuring future additions cannot be silently mishandled. Move the +is_task_work_add_kfunc() forward declaration to the top alongside other +callback-related helpers. We update push_async_cb() to adjust to the new +changes. + +At the same time, while simplifying in_sleepable(), we notice a problem +in do_misc_fixups. Fix storage_get helpers to use GFP_ATOMIC when called +from non-sleepable contexts within sleepable programs, such as bpf_timer +callbacks. + +Currently, the check in do_misc_fixups assumes that env->prog->sleepable, +previously in_sleepable(env) which only resolved to this check before +last commit, holds across the program's execution, but that is not true. +Instead, the func_atomic bit must be set whenever we see the function +being called in an atomic context. Previously, this is being done when +the helper is invoked in atomic contexts in sleepable programs, we can +simply just set the value to true without doing an in_sleepable() check. + +We must also do a standalone in_sleepable() check to handle cases where +the async callback itself is armed from a sleepable program, but is +itself non-sleepable (e.g., timer callback) and invokes such a helper, +thus needing the func_atomic bit to be true for the said call. + +Adjust do_misc_fixups() to drop any checks regarding sleepable nature of +the program, and just depend on the func_atomic bit to decide which GFP +flag to pass. + +Fixes: 81f1d7a583fa ("bpf: wq: add bpf_wq_set_callback_impl") +Fixes: b00fa38a9c1c ("bpf: Enable non-atomic allocations in local storage") +Acked-by: Eduard Zingerman +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251007220349.3852807-2-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 41 ++++++++++++++++++++++++++++++----------- + 1 file changed, 30 insertions(+), 11 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index fbe4bb91c564a..460107b0449fe 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -515,6 +515,7 @@ static bool is_callback_calling_kfunc(u32 btf_id); + static bool is_bpf_throw_kfunc(struct bpf_insn *insn); + + static bool is_bpf_wq_set_callback_impl_kfunc(u32 btf_id); ++static bool is_task_work_add_kfunc(u32 func_id); + + static bool is_sync_callback_calling_function(enum bpf_func_id func_id) + { +@@ -547,6 +548,21 @@ static bool is_async_callback_calling_insn(struct bpf_insn *insn) + (bpf_pseudo_kfunc_call(insn) && is_async_callback_calling_kfunc(insn->imm)); + } + ++static bool is_async_cb_sleepable(struct bpf_verifier_env *env, struct bpf_insn *insn) ++{ ++ /* bpf_timer callbacks are never sleepable. */ ++ if (bpf_helper_call(insn) && insn->imm == BPF_FUNC_timer_set_callback) ++ return false; ++ ++ /* bpf_wq and bpf_task_work callbacks are always sleepable. */ ++ if (bpf_pseudo_kfunc_call(insn) && insn->off == 0 && ++ (is_bpf_wq_set_callback_impl_kfunc(insn->imm) || is_task_work_add_kfunc(insn->imm))) ++ return true; ++ ++ verifier_bug(env, "unhandled async callback in is_async_cb_sleepable"); ++ return false; ++} ++ + static bool is_may_goto_insn(struct bpf_insn *insn) + { + return insn->code == (BPF_JMP | BPF_JCOND) && insn->src_reg == BPF_MAY_GOTO; +@@ -5826,8 +5842,7 @@ static int map_kptr_match_type(struct bpf_verifier_env *env, + + static bool in_sleepable(struct bpf_verifier_env *env) + { +- return env->prog->sleepable || +- (env->cur_state && env->cur_state->in_sleepable); ++ return env->cur_state->in_sleepable; + } + + /* The non-sleepable programs and sleepable programs with explicit bpf_rcu_read_lock() +@@ -10368,8 +10383,6 @@ typedef int (*set_callee_state_fn)(struct bpf_verifier_env *env, + struct bpf_func_state *callee, + int insn_idx); + +-static bool is_task_work_add_kfunc(u32 func_id); +- + static int set_callee_state(struct bpf_verifier_env *env, + struct bpf_func_state *caller, + struct bpf_func_state *callee, int insn_idx); +@@ -10588,8 +10601,7 @@ static int push_callback_call(struct bpf_verifier_env *env, struct bpf_insn *ins + env->subprog_info[subprog].is_async_cb = true; + async_cb = push_async_cb(env, env->subprog_info[subprog].start, + insn_idx, subprog, +- is_bpf_wq_set_callback_impl_kfunc(insn->imm) || +- is_task_work_add_kfunc(insn->imm)); ++ is_async_cb_sleepable(env, insn)); + if (!async_cb) + return -EFAULT; + callee = async_cb->frame[0]; +@@ -11428,7 +11440,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + return -EINVAL; + } + +- if (in_sleepable(env) && is_storage_get_function(func_id)) ++ if (is_storage_get_function(func_id)) + env->insn_aux_data[insn_idx].storage_get_func_atomic = true; + } + +@@ -11439,7 +11451,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + return -EINVAL; + } + +- if (in_sleepable(env) && is_storage_get_function(func_id)) ++ if (is_storage_get_function(func_id)) + env->insn_aux_data[insn_idx].storage_get_func_atomic = true; + } + +@@ -11450,10 +11462,17 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + return -EINVAL; + } + +- if (in_sleepable(env) && is_storage_get_function(func_id)) ++ if (is_storage_get_function(func_id)) + env->insn_aux_data[insn_idx].storage_get_func_atomic = true; + } + ++ /* ++ * Non-sleepable contexts in sleepable programs (e.g., timer callbacks) ++ * are atomic and must use GFP_ATOMIC for storage_get helpers. ++ */ ++ if (!in_sleepable(env) && is_storage_get_function(func_id)) ++ env->insn_aux_data[insn_idx].storage_get_func_atomic = true; ++ + meta.func_id = func_id; + /* check args */ + for (i = 0; i < MAX_BPF_FUNC_REG_ARGS; i++) { +@@ -22485,8 +22504,7 @@ static int do_misc_fixups(struct bpf_verifier_env *env) + } + + if (is_storage_get_function(insn->imm)) { +- if (!in_sleepable(env) || +- env->insn_aux_data[i + delta].storage_get_func_atomic) ++ if (env->insn_aux_data[i + delta].storage_get_func_atomic) + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_5, (__force __s32)GFP_ATOMIC); + else + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_5, (__force __s32)GFP_KERNEL); +@@ -23156,6 +23174,7 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog) + state->curframe = 0; + state->speculative = false; + state->branches = 1; ++ state->in_sleepable = env->prog->sleepable; + state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL_ACCOUNT); + if (!state->frame[0]) { + kfree(state); +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch b/queue-6.18/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch new file mode 100644 index 0000000000..e849bfe0f1 --- /dev/null +++ b/queue-6.18/bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch @@ -0,0 +1,83 @@ +From a91b11a012dd34a120f09fdca7545282226e47a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:29:41 +0000 +Subject: bpf: Fix stackmap overflow check in __bpf_get_stackid() + +From: Arnaud Lecomte + +[ Upstream commit 23f852daa4bab4d579110e034e4d513f7d490846 ] + +Syzkaller reported a KASAN slab-out-of-bounds write in __bpf_get_stackid() +when copying stack trace data. The issue occurs when the perf trace + contains more stack entries than the stack map bucket can hold, + leading to an out-of-bounds write in the bucket's data array. + +Fixes: ee2a098851bf ("bpf: Adjust BPF stack helper functions to accommodate skip > 0") +Reported-by: syzbot+c9b724fbb41cf2538b7b@syzkaller.appspotmail.com +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192941.1500-1-contact@arnaud-lcm.com + +Closes: https://syzkaller.appspot.com/bug?extid=c9b724fbb41cf2538b7b +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index 5e9ad050333c2..2365541c81dd1 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -251,8 +251,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + { + struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map); + struct stack_map_bucket *bucket, *new_bucket, *old_bucket; ++ u32 hash, id, trace_nr, trace_len, i, max_depth; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +- u32 hash, id, trace_nr, trace_len, i; + bool user = flags & BPF_F_USER_STACK; + u64 *ips; + bool hash_matches; +@@ -261,7 +261,8 @@ static long __bpf_get_stackid(struct bpf_map *map, + /* skipping more than usable stack trace */ + return -EFAULT; + +- trace_nr = trace->nr - skip; ++ max_depth = stack_map_calculate_max_depth(map->value_size, stack_map_data_size(map), flags); ++ trace_nr = min_t(u32, trace->nr - skip, max_depth - skip); + trace_len = trace_nr * sizeof(u64); + ips = trace->ip + skip; + hash = jhash2((u32 *)ips, trace_len / sizeof(u32), 0); +@@ -390,15 +391,11 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + return -EFAULT; + + nr_kernel = count_kernel_ip(trace); ++ __u64 nr = trace->nr; /* save original */ + + if (kernel) { +- __u64 nr = trace->nr; +- + trace->nr = nr_kernel; + ret = __bpf_get_stackid(map, trace, flags); +- +- /* restore nr */ +- trace->nr = nr; + } else { /* user */ + u64 skip = flags & BPF_F_SKIP_FIELD_MASK; + +@@ -409,6 +406,10 @@ BPF_CALL_3(bpf_get_stackid_pe, struct bpf_perf_event_data_kern *, ctx, + flags = (flags & ~BPF_F_SKIP_FIELD_MASK) | skip; + ret = __bpf_get_stackid(map, trace, flags); + } ++ ++ /* restore nr */ ++ trace->nr = nr; ++ + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/bpf-free-special-fields-when-update-lru_-percpu_hash.patch b/queue-6.18/bpf-free-special-fields-when-update-lru_-percpu_hash.patch new file mode 100644 index 0000000000..d8b96d2aa8 --- /dev/null +++ b/queue-6.18/bpf-free-special-fields-when-update-lru_-percpu_hash.patch @@ -0,0 +1,58 @@ +From 3eec9b7192a3b4c5b239de3ca6df97c334546f67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 23:14:06 +0800 +Subject: bpf: Free special fields when update [lru_,]percpu_hash maps + +From: Leon Hwang + +[ Upstream commit 6af6e49a76c9af7d42eb923703e7648cb2bf401a ] + +As [lru_,]percpu_hash maps support BPF_KPTR_{REF,PERCPU}, missing +calls to 'bpf_obj_free_fields()' in 'pcpu_copy_value()' could cause the +memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the +map gets freed. + +Fix this by calling 'bpf_obj_free_fields()' after +'copy_map_value[,_long]()' in 'pcpu_copy_value()'. + +Fixes: 65334e64a493 ("bpf: Support kptrs in percpu hashmap and percpu LRU hashmap") +Signed-off-by: Leon Hwang +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20251105151407.12723-2-leon.hwang@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index c2fcd0cd51e51..e7721f0776c72 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -947,15 +947,21 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) + static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, + void *value, bool onallcpus) + { ++ void *ptr; ++ + if (!onallcpus) { + /* copy true value_size bytes */ +- copy_map_value(&htab->map, this_cpu_ptr(pptr), value); ++ ptr = this_cpu_ptr(pptr); ++ copy_map_value(&htab->map, ptr, value); ++ bpf_obj_free_fields(htab->map.record, ptr); + } else { + u32 size = round_up(htab->map.value_size, 8); + int off = 0, cpu; + + for_each_possible_cpu(cpu) { +- copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value + off); ++ ptr = per_cpu_ptr(pptr, cpu); ++ copy_map_value_long(&htab->map, ptr, value + off); ++ bpf_obj_free_fields(htab->map.record, ptr); + off += size; + } + } +-- +2.51.0 + diff --git a/queue-6.18/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch b/queue-6.18/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch new file mode 100644 index 0000000000..9f7be12a98 --- /dev/null +++ b/queue-6.18/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch @@ -0,0 +1,40 @@ +From 8b74680cf65447cccadd9e949f87483f895324a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:07:05 +0800 +Subject: bpf: Handle return value of ftrace_set_filter_ip in register_fentry + +From: Menglong Dong + +[ Upstream commit fea3f5e83c5cd80a76d97343023a2f2e6bd862bf ] + +The error that returned by ftrace_set_filter_ip() in register_fentry() is +not handled properly. Just fix it. + +Fixes: 00963a2e75a8 ("bpf: Support bpf_trampoline on functions with IPMODIFY (e.g. livepatch)") +Signed-off-by: Menglong Dong +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251110120705.1553694-1-dongml2@chinatelecom.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/trampoline.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index f2cb0b0970933..04104397c432e 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -220,7 +220,9 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr) + } + + if (tr->func.ftrace_managed) { +- ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ if (ret) ++ return ret; + ret = register_ftrace_direct(tr->fops, (long)new_addr); + } else { + ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); +-- +2.51.0 + diff --git a/queue-6.18/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch b/queue-6.18/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch new file mode 100644 index 0000000000..3b2d886235 --- /dev/null +++ b/queue-6.18/bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch @@ -0,0 +1,63 @@ +From 01bff2f1ea02c0ad96bdddd68d8ce7f3eaa94170 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:19:22 +0530 +Subject: bpf: Prevent nesting overflow in bpf_try_get_buffers + +From: Sahil Chandna + +[ Upstream commit c1da3df7191f1b4df9256bcd30d78f78201e1d17 ] + +bpf_try_get_buffers() returns one of multiple per-CPU buffers based on a +per-CPU nesting counter. This mechanism expects that buffers are not +endlessly acquired before being returned. migrate_disable() ensures that a +task remains on the same CPU, but it does not prevent the task from being +preempted by another task on that CPU. + +Without disabled preemption, a task may be preempted while holding a +buffer, allowing another task to run on same CPU and acquire an +additional buffer. Several such preemptions can cause the per-CPU +nest counter to exceed MAX_BPRINTF_NEST_LEVEL and trigger the warning in +bpf_try_get_buffers(). Adding preempt_disable()/preempt_enable() around +buffer acquisition and release prevents this task preemption and +preserves the intended bounded nesting behavior. + +Reported-by: syzbot+b0cff308140f79a9c4cb@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68f6a4c8.050a0220.1be48.0011.GAE@google.com/ +Fixes: 4223bf833c849 ("bpf: Remove preempt_disable in bpf_try_get_buffers") +Suggested-by: Yonghong Song +Reviewed-by: Sebastian Andrzej Siewior +Signed-off-by: Sahil Chandna +Link: https://lore.kernel.org/r/20251114064922.11650-1-chandna.sahil@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/helpers.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c +index e4007fea49091..81ef159ef89bd 100644 +--- a/kernel/bpf/helpers.c ++++ b/kernel/bpf/helpers.c +@@ -777,9 +777,11 @@ int bpf_try_get_buffers(struct bpf_bprintf_buffers **bufs) + { + int nest_level; + ++ preempt_disable(); + nest_level = this_cpu_inc_return(bpf_bprintf_nest_level); + if (WARN_ON_ONCE(nest_level > MAX_BPRINTF_NEST_LEVEL)) { + this_cpu_dec(bpf_bprintf_nest_level); ++ preempt_enable(); + return -EBUSY; + } + *bufs = this_cpu_ptr(&bpf_bprintf_bufs[nest_level - 1]); +@@ -792,6 +794,7 @@ void bpf_put_buffers(void) + if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0)) + return; + this_cpu_dec(bpf_bprintf_nest_level); ++ preempt_enable(); + } + + void bpf_bprintf_cleanup(struct bpf_bprintf_data *data) +-- +2.51.0 + diff --git a/queue-6.18/bpf-properly-verify-tail-call-behavior.patch b/queue-6.18/bpf-properly-verify-tail-call-behavior.patch new file mode 100644 index 0000000000..450a7231fc --- /dev/null +++ b/queue-6.18/bpf-properly-verify-tail-call-behavior.patch @@ -0,0 +1,114 @@ +From e7b1d7bd7115865dd6be3b02b0d4320c41a812e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 17:03:52 +0100 +Subject: bpf: properly verify tail call behavior + +From: Martin Teichmann + +[ Upstream commit e3245f8990431950d20631c72236d4e8cb2dcde8 ] + +A successful ebpf tail call does not return to the caller, but to the +caller-of-the-caller, often just finishing the ebpf program altogether. + +Any restrictions that the verifier needs to take into account - notably +the fact that the tail call might have modified packet pointers - are to +be checked on the caller-of-the-caller. Checking it on the caller made +the verifier refuse perfectly fine programs that would use the packet +pointers after a tail call, which is no problem as this code is only +executed if the tail call was unsuccessful, i.e. nothing happened. + +This patch simulates the behavior of a tail call in the verifier. A +conditional jump to the code after the tail call is added for the case +of an unsucessful tail call, and a return to the caller is simulated for +a successful tail call. + +For the successful case we assume that the tail call returns an int, +as tail calls are currently only allowed in functions that return and +int. We always assume that the tail call modified the packet pointers, +as we do not know what the tail call did. + +For the unsuccessful case we know nothing happened, so we do not need to +add new constraints. + +This approach also allows to check other problems that may occur with +tail calls, namely we are now able to check that precision is properly +propagated into subprograms using tail calls, as well as checking the +live slots in such a subprogram. + +Fixes: 1a4607ffba35 ("bpf: consider that tail calls invalidate packet pointers") +Link: https://lore.kernel.org/bpf/20251029105828.1488347-1-martin.teichmann@xfel.eu/ +Signed-off-by: Martin Teichmann +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/r/20251119160355.1160932-2-martin.teichmann@xfel.eu +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 31 ++++++++++++++++++++++++++++--- + 1 file changed, 28 insertions(+), 3 deletions(-) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index 52c01c011c6fb..89560e455ce7b 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -4408,6 +4408,11 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx, + bt_reg_mask(bt)); + return -EFAULT; + } ++ if (insn->src_reg == BPF_REG_0 && insn->imm == BPF_FUNC_tail_call ++ && subseq_idx - idx != 1) { ++ if (bt_subprog_enter(bt)) ++ return -EFAULT; ++ } + } else if (opcode == BPF_EXIT) { + bool r0_precise; + +@@ -10995,6 +11000,10 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx) + bool in_callback_fn; + int err; + ++ err = bpf_update_live_stack(env); ++ if (err) ++ return err; ++ + callee = state->frame[state->curframe]; + r0 = &callee->regs[BPF_REG_0]; + if (r0->type == PTR_TO_STACK) { +@@ -11912,6 +11921,25 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn + env->prog->call_get_func_ip = true; + } + ++ if (func_id == BPF_FUNC_tail_call) { ++ if (env->cur_state->curframe) { ++ struct bpf_verifier_state *branch; ++ ++ mark_reg_scratched(env, BPF_REG_0); ++ branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false); ++ if (IS_ERR(branch)) ++ return PTR_ERR(branch); ++ clear_all_pkt_pointers(env); ++ mark_reg_unknown(env, regs, BPF_REG_0); ++ err = prepare_func_exit(env, &env->insn_idx); ++ if (err) ++ return err; ++ env->insn_idx--; ++ } else { ++ changes_data = false; ++ } ++ } ++ + if (changes_data) + clear_all_pkt_pointers(env); + return 0; +@@ -19810,9 +19838,6 @@ static int process_bpf_exit_full(struct bpf_verifier_env *env, + return PROCESS_BPF_EXIT; + + if (env->cur_state->curframe) { +- err = bpf_update_live_stack(env); +- if (err) +- return err; + /* exit from nested function */ + err = prepare_func_exit(env, &env->insn_idx); + if (err) +-- +2.51.0 + diff --git a/queue-6.18/bpf-refactor-stack-map-trace-depth-calculation-into-.patch b/queue-6.18/bpf-refactor-stack-map-trace-depth-calculation-into-.patch new file mode 100644 index 0000000000..05803d8d01 --- /dev/null +++ b/queue-6.18/bpf-refactor-stack-map-trace-depth-calculation-into-.patch @@ -0,0 +1,135 @@ +From f30829a5d88776e6ba3771441657cb50dea0b716 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 19:28:58 +0000 +Subject: bpf: Refactor stack map trace depth calculation into helper function + +From: Arnaud Lecomte + +[ Upstream commit e17d62fedd10ae56e2426858bd0757da544dbc73 ] + +Extract the duplicated maximum allowed depth computation for stack +traces stored in BPF stacks from bpf_get_stackid() and __bpf_get_stack() +into a dedicated stack_map_calculate_max_depth() helper function. + +This unifies the logic for: +- The max depth computation +- Enforcing the sysctl_perf_event_max_stack limit + +No functional changes for existing code paths. + +Signed-off-by: Arnaud Lecomte +Signed-off-by: Andrii Nakryiko +Acked-by: Yonghong Song +Acked-by: Song Liu +Link: https://lore.kernel.org/bpf/20251025192858.31424-1-contact@arnaud-lcm.com +Stable-dep-of: 23f852daa4ba ("bpf: Fix stackmap overflow check in __bpf_get_stackid()") +Signed-off-by: Sasha Levin +--- + kernel/bpf/stackmap.c | 47 +++++++++++++++++++++++++++++-------------- + 1 file changed, 32 insertions(+), 15 deletions(-) + +diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c +index 4d53cdd1374cf..5e9ad050333c2 100644 +--- a/kernel/bpf/stackmap.c ++++ b/kernel/bpf/stackmap.c +@@ -42,6 +42,28 @@ static inline int stack_map_data_size(struct bpf_map *map) + sizeof(struct bpf_stack_build_id) : sizeof(u64); + } + ++/** ++ * stack_map_calculate_max_depth - Calculate maximum allowed stack trace depth ++ * @size: Size of the buffer/map value in bytes ++ * @elem_size: Size of each stack trace element ++ * @flags: BPF stack trace flags (BPF_F_USER_STACK, BPF_F_USER_BUILD_ID, ...) ++ * ++ * Return: Maximum number of stack trace entries that can be safely stored ++ */ ++static u32 stack_map_calculate_max_depth(u32 size, u32 elem_size, u64 flags) ++{ ++ u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 max_depth; ++ u32 curr_sysctl_max_stack = READ_ONCE(sysctl_perf_event_max_stack); ++ ++ max_depth = size / elem_size; ++ max_depth += skip; ++ if (max_depth > curr_sysctl_max_stack) ++ return curr_sysctl_max_stack; ++ ++ return max_depth; ++} ++ + static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) + { + u64 elem_size = sizeof(struct stack_map_bucket) + +@@ -300,20 +322,17 @@ static long __bpf_get_stackid(struct bpf_map *map, + BPF_CALL_3(bpf_get_stackid, struct pt_regs *, regs, struct bpf_map *, map, + u64, flags) + { +- u32 max_depth = map->value_size / stack_map_data_size(map); +- u32 skip = flags & BPF_F_SKIP_FIELD_MASK; ++ u32 elem_size = stack_map_data_size(map); + bool user = flags & BPF_F_USER_STACK; + struct perf_callchain_entry *trace; + bool kernel = !user; ++ u32 max_depth; + + if (unlikely(flags & ~(BPF_F_SKIP_FIELD_MASK | BPF_F_USER_STACK | + BPF_F_FAST_STACK_CMP | BPF_F_REUSE_STACKID))) + return -EINVAL; + +- max_depth += skip; +- if (max_depth > sysctl_perf_event_max_stack) +- max_depth = sysctl_perf_event_max_stack; +- ++ max_depth = stack_map_calculate_max_depth(map->value_size, elem_size, flags); + trace = get_perf_callchain(regs, kernel, user, max_depth, + false, false); + +@@ -406,7 +425,7 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + struct perf_callchain_entry *trace_in, + void *buf, u32 size, u64 flags, bool may_fault) + { +- u32 trace_nr, copy_len, elem_size, num_elem, max_depth; ++ u32 trace_nr, copy_len, elem_size, max_depth; + bool user_build_id = flags & BPF_F_USER_BUILD_ID; + bool crosstask = task && task != current; + u32 skip = flags & BPF_F_SKIP_FIELD_MASK; +@@ -438,21 +457,20 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + goto clear; + } + +- num_elem = size / elem_size; +- max_depth = num_elem + skip; +- if (sysctl_perf_event_max_stack < max_depth) +- max_depth = sysctl_perf_event_max_stack; ++ max_depth = stack_map_calculate_max_depth(size, elem_size, flags); + + if (may_fault) + rcu_read_lock(); /* need RCU for perf's callchain below */ + +- if (trace_in) ++ if (trace_in) { + trace = trace_in; +- else if (kernel && task) ++ trace->nr = min_t(u32, trace->nr, max_depth); ++ } else if (kernel && task) { + trace = get_callchain_entry_for_task(task, max_depth); +- else ++ } else { + trace = get_perf_callchain(regs, kernel, user, max_depth, + crosstask, false); ++ } + + if (unlikely(!trace) || trace->nr < skip) { + if (may_fault) +@@ -461,7 +479,6 @@ static long __bpf_get_stack(struct pt_regs *regs, struct task_struct *task, + } + + trace_nr = trace->nr - skip; +- trace_nr = (trace_nr <= num_elem) ? trace_nr : num_elem; + copy_len = trace_nr * elem_size; + + ips = trace->ip + skip; +-- +2.51.0 + diff --git a/queue-6.18/bpftool-allow-bpftool-to-build-with-openssl-3.patch b/queue-6.18/bpftool-allow-bpftool-to-build-with-openssl-3.patch new file mode 100644 index 0000000000..cce5c0ffc3 --- /dev/null +++ b/queue-6.18/bpftool-allow-bpftool-to-build-with-openssl-3.patch @@ -0,0 +1,49 @@ +From 17f82683a8e9aeda51b84d0a17cde04b6d2d6223 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 08:47:53 +0000 +Subject: bpftool: Allow bpftool to build with openssl < 3 + +From: Alan Maguire + +[ Upstream commit 90ae54b4c7eca42d5ce006dd0a8cb0b5bfbf80d0 ] + +ERR_get_error_all()[1] is a openssl v3 API, so to make code +compatible with openssl v1 utilize ERR_get_err_line_data +instead. Since openssl is already a build requirement for +the kernel (minimum requirement openssl 1.0.0), this will +allow bpftool to compile where opensslv3 is not available. +Signing-related BPF selftests pass with openssl v1. + +[1] https://docs.openssl.org/3.4/man3/ERR_get_error/ + +Fixes: 40863f4d6ef2 ("bpftool: Add support for signing BPF programs") +Signed-off-by: Alan Maguire +Acked-by: Song Liu +Acked-by: Quentin Monnet +Link: https://lore.kernel.org/r/20251120084754.640405-2-alan.maguire@oracle.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/bpf/bpftool/sign.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/tools/bpf/bpftool/sign.c b/tools/bpf/bpftool/sign.c +index b34f74d210e9c..f9b742f4bb104 100644 +--- a/tools/bpf/bpftool/sign.c ++++ b/tools/bpf/bpftool/sign.c +@@ -28,6 +28,12 @@ + + #define OPEN_SSL_ERR_BUF_LEN 256 + ++/* Use deprecated in 3.0 ERR_get_error_line_data for openssl < 3 */ ++#if !defined(OPENSSL_VERSION_MAJOR) || (OPENSSL_VERSION_MAJOR < 3) ++#define ERR_get_error_all(file, line, func, data, flags) \ ++ ERR_get_error_line_data(file, line, data, flags) ++#endif ++ + static void display_openssl_errors(int l) + { + char buf[OPEN_SSL_ERR_BUF_LEN]; +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-double-free-of-qgroup-record-after-failure.patch b/queue-6.18/btrfs-fix-double-free-of-qgroup-record-after-failure.patch new file mode 100644 index 0000000000..0db2e36686 --- /dev/null +++ b/queue-6.18/btrfs-fix-double-free-of-qgroup-record-after-failure.patch @@ -0,0 +1,155 @@ +From 277923c563c0e1f55d16b1c152fca22bd0104123 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 20:05:03 +0200 +Subject: btrfs: fix double free of qgroup record after failure to add delayed + ref head +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Miquel Sabaté Solà + +[ Upstream commit 725e46298876a2cc1f1c3fb22ba69d29102c3ddf ] + +In the previous code it was possible to incur into a double kfree() +scenario when calling add_delayed_ref_head(). This could happen if the +record was reported to already exist in the +btrfs_qgroup_trace_extent_nolock() call, but then there was an error +later on add_delayed_ref_head(). In this case, since +add_delayed_ref_head() returned an error, the caller went to free the +record. Since add_delayed_ref_head() couldn't set this kfree'd pointer +to NULL, then kfree() would have acted on a non-NULL 'record' object +which was pointing to memory already freed by the callee. + +The problem comes from the fact that the responsibility to kfree the +object is on both the caller and the callee at the same time. Hence, the +fix for this is to shift the ownership of the 'qrecord' object out of +the add_delayed_ref_head(). That is, we will never attempt to kfree() +the given object inside of this function, and will expect the caller to +act on the 'qrecord' object on its own. The only exception where the +'qrecord' object cannot be kfree'd is if it was inserted into the +tracing logic, for which we already have the 'qrecord_inserted_ret' +boolean to account for this. Hence, the caller has to kfree the object +only if add_delayed_ref_head() reports not to have inserted it on the +tracing logic. + +As a side-effect of the above, we must guarantee that +'qrecord_inserted_ret' is properly initialized at the start of the +function, not at the end, and then set when an actual insert +happens. This way we avoid 'qrecord_inserted_ret' having an invalid +value on an early exit. + +The documentation from the add_delayed_ref_head() has also been updated +to reflect on the exact ownership of the 'qrecord' object. + +Fixes: 6ef8fbce0104 ("btrfs: fix missing error handling when adding delayed ref with qgroups enabled") +Reviewed-by: Filipe Manana +Signed-off-by: Miquel Sabaté Solà +Signed-off-by: Filipe Manana +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/delayed-ref.c | 43 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 33 insertions(+), 10 deletions(-) + +diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c +index 481802efaa143..f8fc26272f76c 100644 +--- a/fs/btrfs/delayed-ref.c ++++ b/fs/btrfs/delayed-ref.c +@@ -798,9 +798,13 @@ static void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref, + } + + /* +- * helper function to actually insert a head node into the rbtree. +- * this does all the dirty work in terms of maintaining the correct +- * overall modification count. ++ * Helper function to actually insert a head node into the xarray. This does all ++ * the dirty work in terms of maintaining the correct overall modification ++ * count. ++ * ++ * The caller is responsible for calling kfree() on @qrecord. More specifically, ++ * if this function reports that it did not insert it as noted in ++ * @qrecord_inserted_ret, then it's safe to call kfree() on it. + * + * Returns an error pointer in case of an error. + */ +@@ -814,7 +818,14 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + struct btrfs_delayed_ref_head *existing; + struct btrfs_delayed_ref_root *delayed_refs; + const unsigned long index = (head_ref->bytenr >> fs_info->sectorsize_bits); +- bool qrecord_inserted = false; ++ ++ /* ++ * If 'qrecord_inserted_ret' is provided, then the first thing we need ++ * to do is to initialize it to false just in case we have an exit ++ * before trying to insert the record. ++ */ ++ if (qrecord_inserted_ret) ++ *qrecord_inserted_ret = false; + + delayed_refs = &trans->transaction->delayed_refs; + lockdep_assert_held(&delayed_refs->lock); +@@ -833,6 +844,12 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + + /* Record qgroup extent info if provided */ + if (qrecord) { ++ /* ++ * Setting 'qrecord' but not 'qrecord_inserted_ret' will likely ++ * result in a memory leakage. ++ */ ++ ASSERT(qrecord_inserted_ret != NULL); ++ + int ret; + + ret = btrfs_qgroup_trace_extent_nolock(fs_info, delayed_refs, qrecord, +@@ -840,12 +857,10 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + if (ret) { + /* Clean up if insertion fails or item exists. */ + xa_release(&delayed_refs->dirty_extents, index); +- /* Caller responsible for freeing qrecord on error. */ + if (ret < 0) + return ERR_PTR(ret); +- kfree(qrecord); +- } else { +- qrecord_inserted = true; ++ } else if (qrecord_inserted_ret) { ++ *qrecord_inserted_ret = true; + } + } + +@@ -888,8 +903,6 @@ add_delayed_ref_head(struct btrfs_trans_handle *trans, + delayed_refs->num_heads++; + delayed_refs->num_heads_ready++; + } +- if (qrecord_inserted_ret) +- *qrecord_inserted_ret = qrecord_inserted; + + return head_ref; + } +@@ -1049,6 +1062,14 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, + xa_release(&delayed_refs->head_refs, index); + spin_unlock(&delayed_refs->lock); + ret = PTR_ERR(new_head_ref); ++ ++ /* ++ * It's only safe to call kfree() on 'qrecord' if ++ * add_delayed_ref_head() has _not_ inserted it for ++ * tracing. Otherwise we need to handle this here. ++ */ ++ if (!qrecord_reserved || qrecord_inserted) ++ goto free_head_ref; + goto free_record; + } + head_ref = new_head_ref; +@@ -1071,6 +1092,8 @@ static int add_delayed_ref(struct btrfs_trans_handle *trans, + + if (qrecord_inserted) + return btrfs_qgroup_trace_extent_post(trans, record, generic_ref->bytenr); ++ ++ kfree(record); + return 0; + + free_record: +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch b/queue-6.18/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch new file mode 100644 index 0000000000..48f2b0e700 --- /dev/null +++ b/queue-6.18/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch @@ -0,0 +1,41 @@ +From 5dd8b1d306565adfd8e0e1fb70a506f195aa241a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:45 +0000 +Subject: btrfs: fix leaf leak in an error path in btrfs_del_items() + +From: Filipe Manana + +[ Upstream commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 ] + +If the call to btrfs_del_leaf() fails we return without decrementing the +extra ref we took on the leaf, therefore leaking it. Fix this by ensuring +we drop the ref count before returning the error. + +Fixes: 751a27615dda ("btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr()") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 561658aca018b..6e053caa6e101 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -4566,9 +4566,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + if (btrfs_header_nritems(leaf) == 0) { + path->slots[1] = slot; + ret = btrfs_del_leaf(trans, root, path, leaf); ++ free_extent_buffer(leaf); + if (ret < 0) + return ret; +- free_extent_buffer(leaf); + ret = 0; + } else { + /* if we're still in the path, make sure +-- +2.51.0 + diff --git a/queue-6.18/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch b/queue-6.18/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch new file mode 100644 index 0000000000..fc7c466657 --- /dev/null +++ b/queue-6.18/btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch @@ -0,0 +1,255 @@ +From 303d74be9e22b8f0e6b6a85831fdd7fa761f37f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 17:20:22 -0700 +Subject: btrfs: fix racy bitfield write in btrfs_clear_space_info_full() + +From: Boris Burkov + +[ Upstream commit 38e818718c5e04961eea0fa8feff3f100ce40408 ] + +From the memory-barriers.txt document regarding memory barrier ordering +guarantees: + + (*) These guarantees do not apply to bitfields, because compilers often + generate code to modify these using non-atomic read-modify-write + sequences. Do not attempt to use bitfields to synchronize parallel + algorithms. + + (*) Even in cases where bitfields are protected by locks, all fields + in a given bitfield must be protected by one lock. If two fields + in a given bitfield are protected by different locks, the compiler's + non-atomic read-modify-write sequences can cause an update to one + field to corrupt the value of an adjacent field. + +btrfs_space_info has a bitfield sharing an underlying word consisting of +the fields full, chunk_alloc, and flush: + +struct btrfs_space_info { + struct btrfs_fs_info * fs_info; /* 0 8 */ + struct btrfs_space_info * parent; /* 8 8 */ + ... + int clamp; /* 172 4 */ + unsigned int full:1; /* 176: 0 4 */ + unsigned int chunk_alloc:1; /* 176: 1 4 */ + unsigned int flush:1; /* 176: 2 4 */ + ... + +Therefore, to be safe from parallel read-modify-writes losing a write to +one of the bitfield members protected by a lock, all writes to all the +bitfields must use the lock. They almost universally do, except for +btrfs_clear_space_info_full() which iterates over the space_infos and +writes out found->full = 0 without a lock. + +Imagine that we have one thread completing a transaction in which we +finished deleting a block_group and are thus calling +btrfs_clear_space_info_full() while simultaneously the data reclaim +ticket infrastructure is running do_async_reclaim_data_space(): + + T1 T2 +btrfs_commit_transaction + btrfs_clear_space_info_full + data_sinfo->full = 0 + READ: full:0, chunk_alloc:0, flush:1 + do_async_reclaim_data_space(data_sinfo) + spin_lock(&space_info->lock); + if(list_empty(tickets)) + space_info->flush = 0; + READ: full: 0, chunk_alloc:0, flush:1 + MOD/WRITE: full: 0, chunk_alloc:0, flush:0 + spin_unlock(&space_info->lock); + return; + MOD/WRITE: full:0, chunk_alloc:0, flush:1 + +and now data_sinfo->flush is 1 but the reclaim worker has exited. This +breaks the invariant that flush is 0 iff there is no work queued or +running. Once this invariant is violated, future allocations that go +into __reserve_bytes() will add tickets to space_info->tickets but will +see space_info->flush is set to 1 and not queue the work. After this, +they will block forever on the resulting ticket, as it is now impossible +to kick the worker again. + +I also confirmed by looking at the assembly of the affected kernel that +it is doing RMW operations. For example, to set the flush (3rd) bit to 0, +the assembly is: + andb $0xfb,0x60(%rbx) +and similarly for setting the full (1st) bit to 0: + andb $0xfe,-0x20(%rax) + +So I think this is really a bug on practical systems. I have observed +a number of systems in this exact state, but am currently unable to +reproduce it. + +Rather than leaving this footgun lying around for the future, take +advantage of the fact that there is room in the struct anyway, and that +it is already quite large and simply change the three bitfield members to +bools. This avoids writes to space_info->full having any effect on +writes to space_info->flush, regardless of locking. + +Fixes: 957780eb2788 ("Btrfs: introduce ticketed enospc infrastructure") +Reviewed-by: Qu Wenruo +Signed-off-by: Boris Burkov +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/block-group.c | 6 +++--- + fs/btrfs/space-info.c | 22 +++++++++++----------- + fs/btrfs/space-info.h | 6 +++--- + 3 files changed, 17 insertions(+), 17 deletions(-) + +diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c +index 5322ef2ae015e..8bf501fbcc0be 100644 +--- a/fs/btrfs/block-group.c ++++ b/fs/btrfs/block-group.c +@@ -4215,7 +4215,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + mutex_unlock(&fs_info->chunk_mutex); + } else { + /* Proceed with allocation */ +- space_info->chunk_alloc = 1; ++ space_info->chunk_alloc = true; + wait_for_alloc = false; + spin_unlock(&space_info->lock); + } +@@ -4264,7 +4264,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + spin_lock(&space_info->lock); + if (ret < 0) { + if (ret == -ENOSPC) +- space_info->full = 1; ++ space_info->full = true; + else + goto out; + } else { +@@ -4274,7 +4274,7 @@ int btrfs_chunk_alloc(struct btrfs_trans_handle *trans, + + space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; + out: +- space_info->chunk_alloc = 0; ++ space_info->chunk_alloc = false; + spin_unlock(&space_info->lock); + mutex_unlock(&fs_info->chunk_mutex); + +diff --git a/fs/btrfs/space-info.c b/fs/btrfs/space-info.c +index 97452fb5d29b0..85c466c85910a 100644 +--- a/fs/btrfs/space-info.c ++++ b/fs/btrfs/space-info.c +@@ -192,7 +192,7 @@ void btrfs_clear_space_info_full(struct btrfs_fs_info *info) + struct btrfs_space_info *found; + + list_for_each_entry(found, head, list) +- found->full = 0; ++ found->full = false; + } + + /* +@@ -372,7 +372,7 @@ void btrfs_add_bg_to_space_info(struct btrfs_fs_info *info, + space_info->bytes_readonly += block_group->bytes_super; + btrfs_space_info_update_bytes_zone_unusable(space_info, block_group->zone_unusable); + if (block_group->length > 0) +- space_info->full = 0; ++ space_info->full = false; + btrfs_try_granting_tickets(info, space_info); + spin_unlock(&space_info->lock); + +@@ -1146,7 +1146,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + spin_lock(&space_info->lock); + to_reclaim = btrfs_calc_reclaim_metadata_size(fs_info, space_info); + if (!to_reclaim) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1158,7 +1158,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + flush_space(fs_info, space_info, to_reclaim, flush_state, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1201,7 +1201,7 @@ static void do_async_reclaim_metadata_space(struct btrfs_space_info *space_info) + flush_state = FLUSH_DELAYED_ITEMS_NR; + commit_cycles--; + } else { +- space_info->flush = 0; ++ space_info->flush = false; + } + } else { + flush_state = FLUSH_DELAYED_ITEMS_NR; +@@ -1383,7 +1383,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1394,7 +1394,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + flush_space(fs_info, space_info, U64_MAX, ALLOC_CHUNK_FORCE, false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1411,7 +1411,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + data_flush_states[flush_state], false); + spin_lock(&space_info->lock); + if (list_empty(&space_info->tickets)) { +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + return; + } +@@ -1428,7 +1428,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + if (maybe_fail_all_tickets(fs_info, space_info)) + flush_state = 0; + else +- space_info->flush = 0; ++ space_info->flush = false; + } else { + flush_state = 0; + } +@@ -1444,7 +1444,7 @@ static void do_async_reclaim_data_space(struct btrfs_space_info *space_info) + + aborted_fs: + maybe_fail_all_tickets(fs_info, space_info); +- space_info->flush = 0; ++ space_info->flush = false; + spin_unlock(&space_info->lock); + } + +@@ -1825,7 +1825,7 @@ static int __reserve_bytes(struct btrfs_fs_info *fs_info, + */ + maybe_clamp_preempt(fs_info, space_info); + +- space_info->flush = 1; ++ space_info->flush = true; + trace_btrfs_trigger_flush(fs_info, + space_info->flags, + orig_bytes, flush, +diff --git a/fs/btrfs/space-info.h b/fs/btrfs/space-info.h +index 679f22efb4073..a846f63585c95 100644 +--- a/fs/btrfs/space-info.h ++++ b/fs/btrfs/space-info.h +@@ -142,11 +142,11 @@ struct btrfs_space_info { + flushing. The value is >> clamp, so turns + out to be a 2^clamp divisor. */ + +- unsigned int full:1; /* indicates that we cannot allocate any more ++ bool full; /* indicates that we cannot allocate any more + chunks for this space */ +- unsigned int chunk_alloc:1; /* set if we are allocating a chunk */ ++ bool chunk_alloc; /* set if we are allocating a chunk */ + +- unsigned int flush:1; /* set if we are trying to make space */ ++ bool flush; /* set if we are trying to make space */ + + unsigned int force_alloc; /* set if we need to force a chunk + alloc for this space */ +-- +2.51.0 + diff --git a/queue-6.18/btrfs-make-sure-extent-and-csum-paths-are-always-rel.patch b/queue-6.18/btrfs-make-sure-extent-and-csum-paths-are-always-rel.patch new file mode 100644 index 0000000000..3e6be7cad0 --- /dev/null +++ b/queue-6.18/btrfs-make-sure-extent-and-csum-paths-are-always-rel.patch @@ -0,0 +1,65 @@ +From e05f05e5fe52f1aadffbfa710dbfb9e25affa828 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 20:28:12 +1030 +Subject: btrfs: make sure extent and csum paths are always released in + scrub_raid56_parity_stripe() + +From: Qu Wenruo + +[ Upstream commit d435c513652e6a90a13c881986a2cc6420c99cab ] + +Unlike queue_scrub_stripe() which uses the global sctx->extent_path and +sctx->csum_path which are always released at the end of scrub_stripe(), +scrub_raid56_parity_stripe() uses local extent_path and csum_path, as +that function is going to handle the full stripe, whose bytenr may be +smaller than the bytenr in the global sctx paths. + +However the cleanup of local extent/csum paths is only happening after +we have successfully submitted an rbio. + +There are several error routes that we didn't release those two paths: + +- scrub_find_fill_first_stripe() errored out at csum tree search + In that case extent_path is still valid, and that function itself will + not release the extent_path passed in. + And the function returns directly without releasing both paths. + +- The full stripe is empty +- Some blocks failed to be recovered +- btrfs_map_block() failed +- raid56_parity_alloc_scrub_rbio() failed + The function returns directly without releasing both paths. + +Fix it by covering btrfs_release_path() calls inside the out: tag. + +This is just a hot fix, in the long run we will go scoped based auto +freeing for both local paths. + +Fixes: 1dc4888e725d ("btrfs: scrub: avoid unnecessary extent tree search preparing stripes") +Fixes: 3c771c194402 ("btrfs: scrub: avoid unnecessary csum tree search preparing stripes") +Signed-off-by: Qu Wenruo +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/scrub.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c +index ba20d9286a340..65361af302343 100644 +--- a/fs/btrfs/scrub.c ++++ b/fs/btrfs/scrub.c +@@ -2230,9 +2230,9 @@ static int scrub_raid56_parity_stripe(struct scrub_ctx *sctx, + bio_put(bio); + btrfs_bio_counter_dec(fs_info); + ++out: + btrfs_release_path(&extent_path); + btrfs_release_path(&csum_path); +-out: + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/cgroup-add-cgroup-namespace-to-tree-after-owner-is-s.patch b/queue-6.18/cgroup-add-cgroup-namespace-to-tree-after-owner-is-s.patch new file mode 100644 index 0000000000..1aa9690b16 --- /dev/null +++ b/queue-6.18/cgroup-add-cgroup-namespace-to-tree-after-owner-is-s.patch @@ -0,0 +1,44 @@ +From 9a6a1c37c64cf2fa554b82fa5e8c9dda01d6c1dc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:20:19 +0100 +Subject: cgroup: add cgroup namespace to tree after owner is set + +From: Christian Brauner + +[ Upstream commit 768b1565d9d1e1eebf7567f477f7f46c05a98a4d ] + +Otherwise we trip VFS_WARN_ON_ONC() in __ns_tree_add_raw(). + +Link: https://patch.msgid.link/20251029-work-namespace-nstree-listns-v4-6-2e6f823ebdc0@kernel.org +Fixes: 7c6059398533 ("cgroup: support ns lookup") +Tested-by: syzbot@syzkaller.appspotmail.com +Reviewed-by: Jeff Layton +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + kernel/cgroup/namespace.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c +index fdbe57578e688..db9617556dd70 100644 +--- a/kernel/cgroup/namespace.c ++++ b/kernel/cgroup/namespace.c +@@ -30,7 +30,6 @@ static struct cgroup_namespace *alloc_cgroup_ns(void) + ret = ns_common_init(new_ns); + if (ret) + return ERR_PTR(ret); +- ns_tree_add(new_ns); + return no_free_ptr(new_ns); + } + +@@ -86,6 +85,7 @@ struct cgroup_namespace *copy_cgroup_ns(u64 flags, + new_ns->ucounts = ucounts; + new_ns->root_cset = cset; + ++ ns_tree_add(new_ns); + return new_ns; + } + +-- +2.51.0 + diff --git a/queue-6.18/cleanup-fix-scoped_class.patch b/queue-6.18/cleanup-fix-scoped_class.patch new file mode 100644 index 0000000000..39e839d8f1 --- /dev/null +++ b/queue-6.18/cleanup-fix-scoped_class.patch @@ -0,0 +1,57 @@ +From cdeba2fdfc55129e0566e0cc54513d850448badb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 00:12:40 +0100 +Subject: cleanup: fix scoped_class() + +From: Christian Brauner + +[ Upstream commit 4e97bae1b412cd6ed8053b3d8a242122952985cc ] + +This is a class, not a guard so why on earth is it checking for guard +pointers or conditional lock acquisition? None of it makes any sense at +all. + +I'm not sure what happened back then. Maybe I had a brief psychedelic +period that I completely forgot about and spaced out into a zone where +that initial macro implementation made any sense at all. + +Link: https://patch.msgid.link/20251103-work-creds-init_cred-v1-1-cb3ec8711a6a@kernel.org +Fixes: 5c21c5f22d07 ("cleanup: add a scoped version of CLASS()") +Reviewed-by: Jens Axboe +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + include/linux/cleanup.h | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/include/linux/cleanup.h b/include/linux/cleanup.h +index 2573585b7f068..19c7e475d3a4d 100644 +--- a/include/linux/cleanup.h ++++ b/include/linux/cleanup.h +@@ -290,15 +290,16 @@ static inline class_##_name##_t class_##_name##ext##_constructor(_init_args) \ + class_##_name##_t var __cleanup(class_##_name##_destructor) = \ + class_##_name##_constructor + +-#define scoped_class(_name, var, args) \ +- for (CLASS(_name, var)(args); \ +- __guard_ptr(_name)(&var) || !__is_cond_ptr(_name); \ +- ({ goto _label; })) \ +- if (0) { \ +-_label: \ +- break; \ ++#define __scoped_class(_name, var, _label, args...) \ ++ for (CLASS(_name, var)(args); ; ({ goto _label; })) \ ++ if (0) { \ ++_label: \ ++ break; \ + } else + ++#define scoped_class(_name, var, args...) \ ++ __scoped_class(_name, var, __UNIQUE_ID(label), args) ++ + /* + * DEFINE_GUARD(name, type, lock, unlock): + * trivial wrapper around DEFINE_CLASS() above specifically +-- +2.51.0 + diff --git a/queue-6.18/clk-keystone-fix-compile-testing.patch b/queue-6.18/clk-keystone-fix-compile-testing.patch new file mode 100644 index 0000000000..feea2265ff --- /dev/null +++ b/queue-6.18/clk-keystone-fix-compile-testing.patch @@ -0,0 +1,41 @@ +From 8cb72a0a131bb00ae9fce539f19a4afedb069b94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:53:25 +0100 +Subject: clk: keystone: fix compile testing + +From: Johan Hovold + +[ Upstream commit b276445e98fe28609688fb85b89a81b803910e63 ] + +Some keystone clock drivers can be selected when COMPILE_TEST is +enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk +driver support") they are never actually built. + +Enable compile testing by allowing the build system to process the +keystone drivers. + +Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") +Signed-off-by: Johan Hovold +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/Makefile | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index b74a1767ca278..61ec08404442b 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -125,8 +125,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ + obj-y += imgtec/ + obj-y += imx/ + obj-y += ingenic/ +-obj-$(CONFIG_ARCH_K3) += keystone/ +-obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ ++obj-y += keystone/ + obj-y += mediatek/ + obj-$(CONFIG_ARCH_MESON) += meson/ + obj-y += microchip/ +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch b/queue-6.18/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..9274c0a9b4 --- /dev/null +++ b/queue-6.18/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch @@ -0,0 +1,53 @@ +From 04293e7ad3221cb0becfaebcfcbffbb37beb4f31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:54 +0200 +Subject: clk: qcom: camcc-sm6350: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit ab0e13141d679fdffdd3463a272c5c1b10be1794 ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly, and fixes +CAMCC_MCLK* being stuck off. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 6c272f7b07219..7df12c1311c68 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -145,15 +145,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, + .alpha = 0x0, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), +- .early_output_mask = BIT(3), + .config_ctl_val = 0x20000800, + .config_ctl_hi_val = 0x400003d2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x00004000, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch b/queue-6.18/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..2e49a68976 --- /dev/null +++ b/queue-6.18/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,89 @@ +From ecaf039c040c8c0d90ea05881ecc33d576980fa6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:46 +0300 +Subject: clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit a76ce61d7225934b0a52c8172a8cd944002a8c6f ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM6350 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 8aac97d29ce3f..6c272f7b07219 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -1693,6 +1693,8 @@ static struct clk_branch camcc_sys_tmr_clk = { + }, + }; + ++static struct gdsc titan_top_gdsc; ++ + static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .en_rest_wait_val = 0x2, +@@ -1702,6 +1704,7 @@ static struct gdsc bps_gdsc = { + .name = "bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1714,6 +1717,7 @@ static struct gdsc ipe_0_gdsc = { + .name = "ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1726,6 +1730,7 @@ static struct gdsc ife_0_gdsc = { + .name = "ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_1_gdsc = { +@@ -1737,6 +1742,7 @@ static struct gdsc ife_1_gdsc = { + .name = "ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_2_gdsc = { +@@ -1748,6 +1754,7 @@ static struct gdsc ife_2_gdsc = { + .name = "ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc titan_top_gdsc = { +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch b/queue-6.18/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..4dbd44bbda --- /dev/null +++ b/queue-6.18/clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch @@ -0,0 +1,50 @@ +From 9c24b860cd5a7e827815ff5b4318be36d68312e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:55 +0200 +Subject: clk: qcom: camcc-sm7150: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit 415aad75c7e5cdb72e0672dc1159be1a99535ecd ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly. + +Fixes: 9f0532da4226 ("clk: qcom: Add Camera Clock Controller driver for SM7150") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-2-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm7150.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm7150.c b/drivers/clk/qcom/camcc-sm7150.c +index 4a3baf5d8e858..590548cac45bf 100644 +--- a/drivers/clk/qcom/camcc-sm7150.c ++++ b/drivers/clk/qcom/camcc-sm7150.c +@@ -139,13 +139,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = { + /* 1920MHz configuration */ + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .early_output_mask = BIT(3), +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), + .config_ctl_hi_val = 0x400003d6, + .config_ctl_val = 0x20000954, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch b/queue-6.18/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..0102ee331e --- /dev/null +++ b/queue-6.18/clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,113 @@ +From 66a5658d7e57f45db62a39bcc5a9e842ae349ede Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:45 +0300 +Subject: clk: qcom: camcc-sm8550: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit d8f1121ebf4036884fc9ab1968f606523dd1c1fe ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM8550 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: ccc4e6a061a2 ("clk: qcom: camcc-sm8550: Add camera clock controller driver for SM8550") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-2-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm8550.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm8550.c b/drivers/clk/qcom/camcc-sm8550.c +index 63aed9e4c362d..b8ece8a57a8a9 100644 +--- a/drivers/clk/qcom/camcc-sm8550.c ++++ b/drivers/clk/qcom/camcc-sm8550.c +@@ -3204,6 +3204,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = { + }, + }; + ++static struct gdsc cam_cc_titan_top_gdsc; ++ + static struct gdsc cam_cc_bps_gdsc = { + .gdscr = 0x10004, + .en_rest_wait_val = 0x2, +@@ -3213,6 +3215,7 @@ static struct gdsc cam_cc_bps_gdsc = { + .name = "cam_cc_bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3225,6 +3228,7 @@ static struct gdsc cam_cc_ife_0_gdsc = { + .name = "cam_cc_ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3237,6 +3241,7 @@ static struct gdsc cam_cc_ife_1_gdsc = { + .name = "cam_cc_ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3249,6 +3254,7 @@ static struct gdsc cam_cc_ife_2_gdsc = { + .name = "cam_cc_ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3261,6 +3267,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = { + .name = "cam_cc_ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3273,6 +3280,7 @@ static struct gdsc cam_cc_sbi_gdsc = { + .name = "cam_cc_sbi_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3285,6 +3293,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = { + .name = "cam_cc_sfe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +@@ -3297,6 +3306,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = { + .name = "cam_cc_sfe_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &cam_cc_titan_top_gdsc.pd, + .flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE, + }; + +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-gcc-glymur-update-the-halt-check-flags-for-.patch b/queue-6.18/clk-qcom-gcc-glymur-update-the-halt-check-flags-for-.patch new file mode 100644 index 0000000000..4d19d95044 --- /dev/null +++ b/queue-6.18/clk-qcom-gcc-glymur-update-the-halt-check-flags-for-.patch @@ -0,0 +1,144 @@ +From 05f33e91cb9f131d1ba894ca70b9188a5d134962 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 15:49:00 +0530 +Subject: clk: qcom: gcc-glymur: Update the halt check flags for pipe clocks + +From: Taniya Das + +[ Upstream commit 18da820eb632fbd99167f3fc6650a30db714ddfd ] + +The pipe clocks for PCIE and USB are externally sourced and they should +not be polled by the clock driver. Update the halt_check flags to 'SKIP' +to disable polling for these clocks. + +This helps avoid the clock status stuck at 'off' warnings, which are +benign, since all consumers of the PHYs must initialize a given instance +before performing any operations. + +Fixes: efe504300a17 ("clk: qcom: gcc: Add support for Global Clock Controller") +Reviewed-by: Konrad Dybcio +Signed-off-by: Taniya Das +Reviewed-by: Imran Shaik +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250925-glymur_gcc_usb_fixes-v2-1-ee4619571efe@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-glymur.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-glymur.c b/drivers/clk/qcom/gcc-glymur.c +index 62059120f9720..d938e7dc5b66e 100644 +--- a/drivers/clk/qcom/gcc-glymur.c ++++ b/drivers/clk/qcom/gcc-glymur.c +@@ -6760,7 +6760,7 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = { + + static struct clk_branch gcc_usb3_prim_phy_pipe_clk = { + .halt_reg = 0x3f088, +- .halt_check = BRANCH_HALT_DELAY, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x3f088, + .hwcg_bit = 1, + .clkr = { +@@ -6816,7 +6816,7 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = { + + static struct clk_branch gcc_usb3_sec_phy_pipe_clk = { + .halt_reg = 0xe2078, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xe2078, + .hwcg_bit = 1, + .clkr = { +@@ -6872,7 +6872,7 @@ static struct clk_branch gcc_usb3_tert_phy_com_aux_clk = { + + static struct clk_branch gcc_usb3_tert_phy_pipe_clk = { + .halt_reg = 0xe1078, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xe1078, + .hwcg_bit = 1, + .clkr = { +@@ -6961,7 +6961,7 @@ static struct clk_branch gcc_usb4_0_master_clk = { + + static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { + .halt_reg = 0x2b0f4, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2b0f4, + .enable_mask = BIT(0), +@@ -6979,7 +6979,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = { + + static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = { + .halt_reg = 0x2b04c, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(11), +@@ -7033,7 +7033,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = { + + static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = { + .halt_reg = 0x2b0bc, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x2b0bc, + .hwcg_bit = 1, + .clkr = { +@@ -7196,7 +7196,7 @@ static struct clk_branch gcc_usb4_1_master_clk = { + + static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { + .halt_reg = 0x2d118, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x2d118, + .enable_mask = BIT(0), +@@ -7214,7 +7214,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = { + + static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = { + .halt_reg = 0x2d04c, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(12), +@@ -7268,7 +7268,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = { + + static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = { + .halt_reg = 0x2d0e0, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0x2d0e0, + .hwcg_bit = 1, + .clkr = { +@@ -7431,7 +7431,7 @@ static struct clk_branch gcc_usb4_2_master_clk = { + + static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { + .halt_reg = 0xe00f8, +- .halt_check = BRANCH_HALT, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0xe00f8, + .enable_mask = BIT(0), +@@ -7449,7 +7449,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = { + + static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = { + .halt_reg = 0xe004c, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .clkr = { + .enable_reg = 0x62010, + .enable_mask = BIT(13), +@@ -7503,7 +7503,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = { + + static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = { + .halt_reg = 0xe00c0, +- .halt_check = BRANCH_HALT_VOTED, ++ .halt_check = BRANCH_HALT_SKIP, + .hwcg_reg = 0xe00c0, + .hwcg_bit = 1, + .clkr = { +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch b/queue-6.18/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch new file mode 100644 index 0000000000..397117a8b5 --- /dev/null +++ b/queue-6.18/clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch @@ -0,0 +1,46 @@ +From 2b40f8564f2b37ecf6644bfaf7ef24eda80f1083 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 22:35:26 +0800 +Subject: clk: qcom: gcc-ipq5424: Correct the icc_first_node_id + +From: Luo Jie + +[ Upstream commit 464ce94531f5a62ce29081a9d3c70eb4d525f443 ] + +Update to use the expected icc_first_node_id for registering the icc +clocks, ensuring correct association of clocks with interconnect nodes. + +Fixes: 170f3d2c065e ("clk: qcom: ipq5424: Use icc-clk for enabling NoC related clocks") +Reviewed-by: Konrad Dybcio +Signed-off-by: Luo Jie +Link: https://lore.kernel.org/r/20251014-qcom_ipq5424_nsscc-v7-1-081f4956be02@quicinc.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-ipq5424.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/qcom/gcc-ipq5424.c b/drivers/clk/qcom/gcc-ipq5424.c +index 3d42f3d85c7a9..71afa1b86b723 100644 +--- a/drivers/clk/qcom/gcc-ipq5424.c ++++ b/drivers/clk/qcom/gcc-ipq5424.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: GPL-2.0 + /* + * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3284,6 +3284,7 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = { + .num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws), + .icc_hws = icc_ipq5424_hws, + .num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws), ++ .icc_first_node_id = IPQ_APPS_ID, + }; + + static int gcc_ipq5424_probe(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch b/queue-6.18/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch new file mode 100644 index 0000000000..1b1a77e737 --- /dev/null +++ b/queue-6.18/clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch @@ -0,0 +1,62 @@ +From c5e6d95cb2750ca01084204c8d7afaa7bafa6d05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 15:07:54 +0530 +Subject: clk: qcom: gcc-qcs615: Update the SDCC clock to use shared_floor_ops + +From: Taniya Das + +[ Upstream commit 0820c9373369c83de5202871d02682d583a91a9c ] + +Fix "gcc_sdcc2_apps_clk_src: rcg didn't update its configuration" during +boot. This happens due to the floor_ops tries to update the rcg +configuration even if the clock is not enabled. +The shared_floor_ops ensures that the RCG is safely parked and the new +parent configuration is cached in the parked_cfg when the clock is off. + +Ensure to use the ops for the other SDCC clock instances as well. + +Fixes: 39d6dcf67fe9 ("clk: qcom: gcc: Add support for QCS615 GCC clocks") +Reviewed-by: Abel Vesa +Signed-off-by: Taniya Das +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029-sdcc_rcg2_shared_ops-v3-1-ecf47d9601d1@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-qcs615.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/qcom/gcc-qcs615.c b/drivers/clk/qcom/gcc-qcs615.c +index 9695446bc2a3c..5b3b8dd4f114b 100644 +--- a/drivers/clk/qcom/gcc-qcs615.c ++++ b/drivers/clk/qcom/gcc-qcs615.c +@@ -784,7 +784,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = { + .name = "gcc_sdcc1_apps_clk_src", + .parent_data = gcc_parent_data_1, + .num_parents = ARRAY_SIZE(gcc_parent_data_1), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +@@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = { + .name = "gcc_sdcc1_ice_core_clk_src", + .parent_data = gcc_parent_data_0, + .num_parents = ARRAY_SIZE(gcc_parent_data_0), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +@@ -830,7 +830,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = { + .name = "gcc_sdcc2_apps_clk_src", + .parent_data = gcc_parent_data_8, + .num_parents = ARRAY_SIZE(gcc_parent_data_8), +- .ops = &clk_rcg2_floor_ops, ++ .ops = &clk_rcg2_shared_floor_ops, + }, + }; + +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch b/queue-6.18/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch new file mode 100644 index 0000000000..3c4cbb87f0 --- /dev/null +++ b/queue-6.18/clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch @@ -0,0 +1,37 @@ +From 16ef0c9bb55fc279f4f5ec29d02b23823dbf08b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 00:08:30 +0530 +Subject: clk: qcom: gcc-sm8750: Add a new frequency for sdcc2 clock + +From: Taniya Das + +[ Upstream commit 393f7834cd2b1eaf4a9eff2701e706e73e660dd7 ] + +The SD card support requires a 37.5MHz clock; add it to the frequency +list for the storage SW driver to be able to request for the frequency. + +Fixes: 3267c774f3ff ("clk: qcom: Add support for GCC on SM8750") +Signed-off-by: Taniya Das +Reviewed-by: Imran Shaik +Link: https://lore.kernel.org/r/20250924-sm8750_gcc_sdcc2_frequency-v1-1-541fd321125f@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/gcc-sm8750.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/qcom/gcc-sm8750.c b/drivers/clk/qcom/gcc-sm8750.c +index 8092dd6b37b56..def86b71a3da5 100644 +--- a/drivers/clk/qcom/gcc-sm8750.c ++++ b/drivers/clk/qcom/gcc-sm8750.c +@@ -1012,6 +1012,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = { + static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = { + F(400000, P_BI_TCXO, 12, 1, 4), + F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0), ++ F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0), + F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0), + F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0), + F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0), +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch b/queue-6.18/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch new file mode 100644 index 0000000000..442dd125e1 --- /dev/null +++ b/queue-6.18/clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch @@ -0,0 +1,39 @@ +From 1720b95da332de6c78ed417a7e5549009778dfab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Jun 2025 21:37:58 +0200 +Subject: clk: qcom: rpmh: Define RPMH_IPA_CLK on QCS615 + +From: Konrad Dybcio + +[ Upstream commit 17e4db05930e455770b15b77708a07681ed24efc ] + +This was previously (mis)represented in the interconnect driver, move +the resource under the clk-rpmh driver control, just like we did for +all platforms in the past, see e.g. Commit aa055bf158cd ("clk: qcom: +rpmh: define IPA clocks where required") + +Fixes: 42a1905a10d6 ("clk: qcom: rpmhcc: Add support for QCS615 Clocks") +Signed-off-by: Konrad Dybcio +Reviewed-by: Dmitry Baryshkov +Link: https://lore.kernel.org/r/20250627-topic-qcs615_icc_ipa-v1-4-dc47596cde69@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/clk-rpmh.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/qcom/clk-rpmh.c b/drivers/clk/qcom/clk-rpmh.c +index 63c38cb47bc45..1a98b3a0c528c 100644 +--- a/drivers/clk/qcom/clk-rpmh.c ++++ b/drivers/clk/qcom/clk-rpmh.c +@@ -855,6 +855,7 @@ static struct clk_hw *qcs615_rpmh_clocks[] = { + [RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw, + [RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw, + [RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw, ++ [RPMH_IPA_CLK] = &clk_rpmh_ipa.hw, + }; + + static const struct clk_rpmh_desc clk_rpmh_qcs615 = { +-- +2.51.0 + diff --git a/queue-6.18/clk-qcom-tcsrcc-glymur-update-register-offsets-for-c.patch b/queue-6.18/clk-qcom-tcsrcc-glymur-update-register-offsets-for-c.patch new file mode 100644 index 0000000000..f72e5571a2 --- /dev/null +++ b/queue-6.18/clk-qcom-tcsrcc-glymur-update-register-offsets-for-c.patch @@ -0,0 +1,208 @@ +From 6c6015f84f085e451d737ff90d1a2f70d622447c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 15:32:25 +0530 +Subject: clk: qcom: tcsrcc-glymur: Update register offsets for clock refs + +From: Taniya Das + +[ Upstream commit a4aa1ceb89f5c0d27a55671d88699cf5eae7331b ] + +Update the register offsets for all the clock ref branches to match the +new address mapping in the TCSR subsystem. + +Fixes: 2c1d6ce4f3da ("clk: qcom: Add TCSR clock driver for Glymur SoC") +Signed-off-by: Taniya Das +Reviewed-by: Abel Vesa +Tested-by: Jagadeesh Kona +Link: https://lore.kernel.org/r/20251031-tcsrcc_glymur-v1-1-0efb031f0ac5@oss.qualcomm.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/tcsrcc-glymur.c | 54 ++++++++++++++++---------------- + 1 file changed, 27 insertions(+), 27 deletions(-) + +diff --git a/drivers/clk/qcom/tcsrcc-glymur.c b/drivers/clk/qcom/tcsrcc-glymur.c +index c1f8b6d10b7fd..215bc2ac548da 100644 +--- a/drivers/clk/qcom/tcsrcc-glymur.c ++++ b/drivers/clk/qcom/tcsrcc-glymur.c +@@ -28,10 +28,10 @@ enum { + }; + + static struct clk_branch tcsr_edp_clkref_en = { +- .halt_reg = 0x1c, ++ .halt_reg = 0x60, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x1c, ++ .enable_reg = 0x60, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_edp_clkref_en", +@@ -45,10 +45,10 @@ static struct clk_branch tcsr_edp_clkref_en = { + }; + + static struct clk_branch tcsr_pcie_1_clkref_en = { +- .halt_reg = 0x4, ++ .halt_reg = 0x48, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x4, ++ .enable_reg = 0x48, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_1_clkref_en", +@@ -62,10 +62,10 @@ static struct clk_branch tcsr_pcie_1_clkref_en = { + }; + + static struct clk_branch tcsr_pcie_2_clkref_en = { +- .halt_reg = 0x8, ++ .halt_reg = 0x4c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x8, ++ .enable_reg = 0x4c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_2_clkref_en", +@@ -79,10 +79,10 @@ static struct clk_branch tcsr_pcie_2_clkref_en = { + }; + + static struct clk_branch tcsr_pcie_3_clkref_en = { +- .halt_reg = 0x10, ++ .halt_reg = 0x54, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x10, ++ .enable_reg = 0x54, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_3_clkref_en", +@@ -96,10 +96,10 @@ static struct clk_branch tcsr_pcie_3_clkref_en = { + }; + + static struct clk_branch tcsr_pcie_4_clkref_en = { +- .halt_reg = 0x14, ++ .halt_reg = 0x58, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x14, ++ .enable_reg = 0x58, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_pcie_4_clkref_en", +@@ -113,10 +113,10 @@ static struct clk_branch tcsr_pcie_4_clkref_en = { + }; + + static struct clk_branch tcsr_usb2_1_clkref_en = { +- .halt_reg = 0x28, ++ .halt_reg = 0x6c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x28, ++ .enable_reg = 0x6c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_1_clkref_en", +@@ -130,10 +130,10 @@ static struct clk_branch tcsr_usb2_1_clkref_en = { + }; + + static struct clk_branch tcsr_usb2_2_clkref_en = { +- .halt_reg = 0x2c, ++ .halt_reg = 0x70, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x2c, ++ .enable_reg = 0x70, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_2_clkref_en", +@@ -147,10 +147,10 @@ static struct clk_branch tcsr_usb2_2_clkref_en = { + }; + + static struct clk_branch tcsr_usb2_3_clkref_en = { +- .halt_reg = 0x30, ++ .halt_reg = 0x74, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x30, ++ .enable_reg = 0x74, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_3_clkref_en", +@@ -164,10 +164,10 @@ static struct clk_branch tcsr_usb2_3_clkref_en = { + }; + + static struct clk_branch tcsr_usb2_4_clkref_en = { +- .halt_reg = 0x44, ++ .halt_reg = 0x88, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x44, ++ .enable_reg = 0x88, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb2_4_clkref_en", +@@ -181,10 +181,10 @@ static struct clk_branch tcsr_usb2_4_clkref_en = { + }; + + static struct clk_branch tcsr_usb3_0_clkref_en = { +- .halt_reg = 0x20, ++ .halt_reg = 0x64, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x20, ++ .enable_reg = 0x64, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_0_clkref_en", +@@ -198,10 +198,10 @@ static struct clk_branch tcsr_usb3_0_clkref_en = { + }; + + static struct clk_branch tcsr_usb3_1_clkref_en = { +- .halt_reg = 0x24, ++ .halt_reg = 0x68, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x24, ++ .enable_reg = 0x68, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb3_1_clkref_en", +@@ -215,10 +215,10 @@ static struct clk_branch tcsr_usb3_1_clkref_en = { + }; + + static struct clk_branch tcsr_usb4_1_clkref_en = { +- .halt_reg = 0x0, ++ .halt_reg = 0x44, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x0, ++ .enable_reg = 0x44, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb4_1_clkref_en", +@@ -232,10 +232,10 @@ static struct clk_branch tcsr_usb4_1_clkref_en = { + }; + + static struct clk_branch tcsr_usb4_2_clkref_en = { +- .halt_reg = 0x18, ++ .halt_reg = 0x5c, + .halt_check = BRANCH_HALT_DELAY, + .clkr = { +- .enable_reg = 0x18, ++ .enable_reg = 0x5c, + .enable_mask = BIT(0), + .hw.init = &(const struct clk_init_data) { + .name = "tcsr_usb4_2_clkref_en", +@@ -268,7 +268,7 @@ static const struct regmap_config tcsr_cc_glymur_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +- .max_register = 0x44, ++ .max_register = 0x94, + .fast_io = true, + }; + +-- +2.51.0 + diff --git a/queue-6.18/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch b/queue-6.18/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch new file mode 100644 index 0000000000..2af7dac1e3 --- /dev/null +++ b/queue-6.18/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch @@ -0,0 +1,58 @@ +From 853bae702dd31ba9d10948e02c9b03c05390f04e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 05:04:43 +0200 +Subject: clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle + callback + +From: Marek Vasut + +[ Upstream commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab ] + +R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page +583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) +indicate after reset has been asserted by writing a matching reset bit +into register SRCR, it is mandatory to wait 1ms. + +This 1ms delay is documented on R-Car V4H and V4M, it is currently +unclear whether S4 is affected as well. This patch does apply the extra +delay on R-Car S4 as well. + +Fix the reset driver to respect the additional delay when toggling +resets. Drivers which use separate reset_control_(de)assert() must +assure matching delay in their driver code. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index de1cf7ba45b78..7063d896249ea 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -689,8 +689,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + /* Reset module */ + writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); ++ /* ++ * On R-Car Gen4, delay after SRCR has been written is 1ms. ++ * On older SoCs, delay after SRCR has been written is 35us ++ * (one cycle of the RCLK clock @ ca. 32 kHz). ++ */ ++ if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) ++ usleep_range(1000, 2000); ++ else ++ usleep_range(35, 1000); + + /* Release module from reset state */ + writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +-- +2.51.0 + diff --git a/queue-6.18/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch b/queue-6.18/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch new file mode 100644 index 0000000000..a9882f8e73 --- /dev/null +++ b/queue-6.18/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch @@ -0,0 +1,124 @@ +From 1dc78a90aa10c6776247fc66e268116d7e4d8270 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 18:20:38 +0200 +Subject: clk: renesas: cpg-mssr: Read back reset registers to assure values + latched + +From: Marek Vasut + +[ Upstream commit b91401af6c00ffab003698bfabd4c166df30748b ] + +On R-Car V4H, the PCIEC controller DBI read would generate an SError in +case the controller reset is released by writing SRSTCLR register first, +and immediately afterward reading some PCIEC controller DBI register. +The issue triggers in rcar_gen4_pcie_additional_common_init() on +dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first +read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). + +The reset controller which contains the SRSTCLR register and the PCIEC +controller which contains the DBI register share the same root access +bus, but the bus then splits into separate segments before reaching each +IP. Even if the SRSTCLR write access was posted on the bus before the +DBI read access, it seems the DBI read access may reach the PCIEC +controller before the SRSTCLR write completed, and trigger the SError. + +Mitigate the issue by adding a dummy SRSTCLR read, which assures the +SRSTCLR write completes fully and is latched into the reset controller, +before the PCIEC DBI read access can occur. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Reviewed-by: Wolfram Sang +Tested-by: Geert Uytterhoeven +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 7063d896249ea..a0a68ec0490f7 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -676,18 +676,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, + + #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) + +-static int cpg_mssr_reset(struct reset_controller_dev *rcdev, +- unsigned long id) ++static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, ++ const char *func, bool set, unsigned long id) + { + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + unsigned int reg = id / 32; + unsigned int bit = id % 32; ++ const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; + u32 bitmask = BIT(bit); + +- dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); ++ if (func) ++ dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); ++ ++ writel(bitmask, priv->pub.base0 + off); ++ readl(priv->pub.base0 + off); ++ barrier_data(priv->pub.base0 + off); ++ ++ return 0; ++} ++ ++static int cpg_mssr_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + + /* Reset module */ +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); ++ cpg_mssr_reset_operate(rcdev, "reset", true, id); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -700,36 +714,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- +- return 0; ++ return cpg_mssr_reset_operate(rcdev, NULL, false, id); + } + + static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "assert", true, id); + } + + static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "deassert", false, id); + } + + static int cpg_mssr_status(struct reset_controller_dev *rcdev, +-- +2.51.0 + diff --git a/queue-6.18/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-6.18/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..c6a9c298be --- /dev/null +++ b/queue-6.18/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 2254044ce5e875965e397fbb7170c617406d217c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index dcda19318b2a9..0f5c91b5dfa99 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -1333,9 +1333,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-6.18/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch b/queue-6.18/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch new file mode 100644 index 0000000000..104ff5cd00 --- /dev/null +++ b/queue-6.18/clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch @@ -0,0 +1,49 @@ +From 7e2fe0d5bd1eb4a20e58a7c11a94dae3c631761d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 16:51:23 +0000 +Subject: clk: renesas: r9a09g077: Propagate rate changes to parent clocks + +From: Lad Prabhakar + +[ Upstream commit 145dfd70b9c70e5bc03494a7ce8fa3748ac01af3 ] + +Add the CLK_SET_RATE_PARENT flag to divider clock registration so that rate +changes can propagate to parent clocks when needed. This allows the CPG +divider clocks to request rate adjustments from their parent, ensuring +correct frequency scaling and improved flexibility in clock rate selection. + +Fixes: 065fe720eec6e ("clk: renesas: Add support for R9A09G077 SoC") +Signed-off-by: Lad Prabhakar +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251028165127.991351-2-prabhakar.mahadev-lad.rj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a09g077-cpg.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/r9a09g077-cpg.c b/drivers/clk/renesas/r9a09g077-cpg.c +index af3ef6d58c87c..d12975418a568 100644 +--- a/drivers/clk/renesas/r9a09g077-cpg.c ++++ b/drivers/clk/renesas/r9a09g077-cpg.c +@@ -217,7 +217,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, + + if (core->dtable) + clk_hw = clk_hw_register_divider_table(dev, core->name, +- parent_name, 0, ++ parent_name, CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), +@@ -226,7 +226,7 @@ r9a09g077_cpg_div_clk_register(struct device *dev, + &pub->rmw_lock); + else + clk_hw = clk_hw_register_divider(dev, core->name, +- parent_name, 0, ++ parent_name, CLK_SET_RATE_PARENT, + addr, + GET_SHIFT(core->conf), + GET_WIDTH(core->conf), +-- +2.51.0 + diff --git a/queue-6.18/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch b/queue-6.18/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch new file mode 100644 index 0000000000..3b3c201697 --- /dev/null +++ b/queue-6.18/clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch @@ -0,0 +1,88 @@ +From c45fb5fe5883f935bc99a9a07ef5a4b7c1268884 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 14:03:29 -0500 +Subject: clk: spacemit: Set clk_hw_onecell_data::num before using flex array + +From: Charles Mirabile + +[ Upstream commit 23b2d2fb136959fd0a8e309c70be83d9b8841c7e ] + +When booting with KASAN enabled the following splat is +encountered during probe of the k1 clock driver: + +UBSAN: array-index-out-of-bounds in drivers/clk/spacemit/ccu-k1.c:1044:16 +index 0 is out of range for type 'clk_hw *[*]' +CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.18.0-rc5+ #1 PREEMPT(lazy) +Hardware name: Unknown Unknown Product/Unknown Product, BIOS 2022.10spacemit 10/01/2022 +Call Trace: +[] dump_backtrace+0x28/0x38 +[] show_stack+0x3a/0x50 +[] dump_stack_lvl+0x5a/0x80 +[] dump_stack+0x18/0x20 +[] ubsan_epilogue+0x10/0x48 +[] __ubsan_handle_out_of_bounds+0xa6/0xa8 +[] k1_ccu_probe+0x37e/0x420 +[] platform_probe+0x56/0x98 +[] really_probe+0x9e/0x350 +[] __driver_probe_device+0x80/0x138 +[] driver_probe_device+0x3a/0xd0 +[] __driver_attach+0xac/0x1b8 +[] bus_for_each_dev+0x6c/0xc8 +[] driver_attach+0x26/0x38 +[] bus_add_driver+0x13e/0x268 +[] driver_register+0x52/0x100 +[] __platform_driver_register+0x28/0x38 +[] k1_ccu_driver_init+0x22/0x38 +[] do_one_initcall+0x62/0x2a0 +[] do_initcalls+0x170/0x1a8 +[] kernel_init_freeable+0x16a/0x1e0 +[] kernel_init+0x2c/0x180 +[] ret_from_fork_kernel+0x16/0x1d8 +[] ret_from_fork_kernel_asm+0x16/0x18 +---[ end trace ]--- + +This is bogus and is simply a result of KASAN consulting the +`.num` member of the struct for bounds information (as it should +due to `__counted_by`) and finding 0 set by kzalloc() because it +has not been initialized before the loop that fills in the array. +The easy fix is to just move the line that sets `num` to before +the loop that fills the array so that KASAN has the information +it needs to accurately conclude that the access is valid. + +Fixes: 1b72c59db0add ("clk: spacemit: Add clock support for SpacemiT K1 SoC") +Tested-by: Yanko Kaneti +Signed-off-by: Charles Mirabile +Reviewed-by: Alex Elder +Reviewed-by: Troy Mitchell +Reviewed-by: Yixun Lan +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/spacemit/ccu-k1.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/spacemit/ccu-k1.c b/drivers/clk/spacemit/ccu-k1.c +index f5a9fe6ba1859..4761bc1e3b6e6 100644 +--- a/drivers/clk/spacemit/ccu-k1.c ++++ b/drivers/clk/spacemit/ccu-k1.c +@@ -1018,6 +1018,8 @@ static int spacemit_ccu_register(struct device *dev, + if (!clk_data) + return -ENOMEM; + ++ clk_data->num = data->num; ++ + for (i = 0; i < data->num; i++) { + struct clk_hw *hw = data->hws[i]; + struct ccu_common *common; +@@ -1044,8 +1046,6 @@ static int spacemit_ccu_register(struct device *dev, + clk_data->hws[i] = hw; + } + +- clk_data->num = data->num; +- + ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data); + if (ret) + dev_err(dev, "failed to add clock hardware provider (%d)\n", ret); +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-arm_arch_timer_mmio-prevent-driv.patch b/queue-6.18/clocksource-drivers-arm_arch_timer_mmio-prevent-driv.patch new file mode 100644 index 0000000000..c316938e6a --- /dev/null +++ b/queue-6.18/clocksource-drivers-arm_arch_timer_mmio-prevent-driv.patch @@ -0,0 +1,46 @@ +From 132ce287a4f376434515adfcf2daa4e695b1cc77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 16:32:24 +0100 +Subject: clocksource/drivers/arm_arch_timer_mmio: Prevent driver unbind + +From: Johan Hovold + +[ Upstream commit 6aa10f0e2ef9eba1955be6a9d0a8eaecf6bdb7ae ] + +Clockevents cannot be deregistered so suppress the bind attributes to +prevent the driver from being unbound and releasing the underlying +resources after registration. + +Fixes: 4891f01527bb ("clocksource/drivers/arm_arch_timer: Add standalone MMIO driver") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Acked-by: Marc Zyngier +Link: https://patch.msgid.link/20251111153226.579-2-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/arm_arch_timer_mmio.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/clocksource/arm_arch_timer_mmio.c b/drivers/clocksource/arm_arch_timer_mmio.c +index ebe1987d651eb..d10362692fdd3 100644 +--- a/drivers/clocksource/arm_arch_timer_mmio.c ++++ b/drivers/clocksource/arm_arch_timer_mmio.c +@@ -426,6 +426,7 @@ static struct platform_driver arch_timer_mmio_drv = { + .driver = { + .name = "arch-timer-mmio", + .of_match_table = arch_timer_mmio_of_table, ++ .suppress_bind_attrs = true, + }, + .probe = arch_timer_mmio_probe, + }; +@@ -434,6 +435,7 @@ builtin_platform_driver(arch_timer_mmio_drv); + static struct platform_driver arch_timer_mmio_acpi_drv = { + .driver = { + .name = "gtdt-arm-mmio-timer", ++ .suppress_bind_attrs = true, + }, + .probe = arch_timer_mmio_probe, + }; +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-nxp-pit-prevent-driver-unbind.patch b/queue-6.18/clocksource-drivers-nxp-pit-prevent-driver-unbind.patch new file mode 100644 index 0000000000..fedfc6f77b --- /dev/null +++ b/queue-6.18/clocksource-drivers-nxp-pit-prevent-driver-unbind.patch @@ -0,0 +1,46 @@ +From d0a1063f03d360f47167f8dfcaa90820a76fc327 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 16:32:25 +0100 +Subject: clocksource/drivers/nxp-pit: Prevent driver unbind + +From: Johan Hovold + +[ Upstream commit e25f964cf414dafa6bee5c9c2c0b1d1fb041dc92 ] + +The driver does not support unbinding (e.g. as clockevents cannot be +deregistered) so suppress the bind attributes to prevent the driver from +being unbound and rebound after registration (and disabling the timer +when reprobing fails). + +Even if the driver can currently only be built-in, also switch to +builtin_platform_driver() to prevent it from being unloaded should +modular builds ever be enabled. + +Fixes: bee33f22d7c3 ("clocksource/drivers/nxp-pit: Add NXP Automotive s32g2 / s32g3 support") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20251111153226.579-3-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-pit.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/timer-nxp-pit.c b/drivers/clocksource/timer-nxp-pit.c +index 2d0a3554b6bf7..d1740f18f7180 100644 +--- a/drivers/clocksource/timer-nxp-pit.c ++++ b/drivers/clocksource/timer-nxp-pit.c +@@ -374,9 +374,10 @@ static struct platform_driver nxp_pit_driver = { + .driver = { + .name = "nxp-pit", + .of_match_table = pit_timer_of_match, ++ .suppress_bind_attrs = true, + }, + .probe = pit_timer_probe, + }; +-module_platform_driver(nxp_pit_driver); ++builtin_platform_driver(nxp_pit_driver); + + TIMER_OF_DECLARE(vf610, "fsl,vf610-pit", pit_timer_init); +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-nxp-stm-fix-section-mismatches.patch b/queue-6.18/clocksource-drivers-nxp-stm-fix-section-mismatches.patch new file mode 100644 index 0000000000..9d11eb7af6 --- /dev/null +++ b/queue-6.18/clocksource-drivers-nxp-stm-fix-section-mismatches.patch @@ -0,0 +1,94 @@ +From 8a723309864263d173021ca1b2b626b325546a68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 07:49:43 +0200 +Subject: clocksource/drivers/nxp-stm: Fix section mismatches + +From: Johan Hovold + +[ Upstream commit b452d2c97eeccbf9c7ac5b3d2d9e80bf6d8a23db ] + +Platform drivers can be probed after their init sections have been +discarded (e.g. on probe deferral or manual rebind through sysfs) so the +probe function must not live in init. Device managed resource actions +similarly cannot be discarded. + +The "_probe" suffix of the driver structure name prevents modpost from +warning about this so replace it to catch any similar future issues. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Cc: stable@vger.kernel.org # 6.16 +Cc: Daniel Lezcano +Link: https://patch.msgid.link/20251017054943.7195-1-johan@kernel.org +Stable-dep-of: 6a2416892e89 ("clocksource/drivers/nxp-stm: Prevent driver unbind") +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index 16d52167e949b..c320d764b12e2 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -177,15 +177,15 @@ static void nxp_stm_clocksource_resume(struct clocksource *cs) + nxp_stm_clocksource_enable(cs); + } + +-static void __init devm_clocksource_unregister(void *data) ++static void devm_clocksource_unregister(void *data) + { + struct stm_timer *stm_timer = data; + + clocksource_unregister(&stm_timer->cs); + } + +-static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer, +- const char *name, void __iomem *base, struct clk *clk) ++static int nxp_stm_clocksource_init(struct device *dev, struct stm_timer *stm_timer, ++ const char *name, void __iomem *base, struct clk *clk) + { + int ret; + +@@ -296,9 +296,9 @@ static void nxp_stm_clockevent_resume(struct clock_event_device *ced) + nxp_stm_module_get(stm_timer); + } + +-static int __init nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer, +- const char *name, void __iomem *base, int irq, +- struct clk *clk, int cpu) ++static int nxp_stm_clockevent_per_cpu_init(struct device *dev, struct stm_timer *stm_timer, ++ const char *name, void __iomem *base, int irq, ++ struct clk *clk, int cpu) + { + stm_timer->base = base; + stm_timer->rate = clk_get_rate(clk); +@@ -386,7 +386,7 @@ static irqreturn_t nxp_stm_module_interrupt(int irq, void *dev_id) + return IRQ_HANDLED; + } + +-static int __init nxp_stm_timer_probe(struct platform_device *pdev) ++static int nxp_stm_timer_probe(struct platform_device *pdev) + { + struct stm_timer *stm_timer; + struct device *dev = &pdev->dev; +@@ -482,14 +482,14 @@ static const struct of_device_id nxp_stm_of_match[] = { + }; + MODULE_DEVICE_TABLE(of, nxp_stm_of_match); + +-static struct platform_driver nxp_stm_probe = { ++static struct platform_driver nxp_stm_driver = { + .probe = nxp_stm_timer_probe, + .driver = { + .name = "nxp-stm", + .of_match_table = nxp_stm_of_match, + }, + }; +-module_platform_driver(nxp_stm_probe); ++module_platform_driver(nxp_stm_driver); + + MODULE_DESCRIPTION("NXP System Timer Module driver"); + MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch b/queue-6.18/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch new file mode 100644 index 0000000000..e7b6585466 --- /dev/null +++ b/queue-6.18/clocksource-drivers-nxp-stm-prevent-driver-unbind.patch @@ -0,0 +1,45 @@ +From 3afe65077de84580b595569449c51279c7776c24 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 16:32:26 +0100 +Subject: clocksource/drivers/nxp-stm: Prevent driver unbind + +From: Johan Hovold + +[ Upstream commit 6a2416892e8942f5e2bfe9b85c0164f410a53a2d ] + +Clockevents cannot be deregistered so suppress the bind attributes to +prevent the driver from being unbound and releasing the underlying +resources after registration. + +Even if the driver can currently only be built-in, also switch to +builtin_platform_driver() to prevent it from being unloaded should +modular builds ever be enabled. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20251111153226.579-4-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index c320d764b12e2..1ab907233f481 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -487,9 +487,10 @@ static struct platform_driver nxp_stm_driver = { + .driver = { + .name = "nxp-stm", + .of_match_table = nxp_stm_of_match, ++ .suppress_bind_attrs = true, + }, + }; +-module_platform_driver(nxp_stm_driver); ++builtin_platform_driver(nxp_stm_driver); + + MODULE_DESCRIPTION("NXP System Timer Module driver"); + MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch b/queue-6.18/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch new file mode 100644 index 0000000000..4f52de1692 --- /dev/null +++ b/queue-6.18/clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch @@ -0,0 +1,63 @@ +From 65a00fb93d7d1a4aeed7bbd6d56cf7aa1480ef5d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 17:07:10 +0800 +Subject: clocksource/drivers/ralink: Fix resource leaks in init error path + +From: Haotian Zhang + +[ Upstream commit 2ba8e2aae1324704565a7d4d66f199d056c9e3c6 ] + +The ralink_systick_init() function does not release all acquired resources +on its error paths. If irq_of_parse_and_map() or a subsequent call fails, +the previously created I/O memory mapping and IRQ mapping are leaked. + +Add goto-based error handling labels to ensure that all allocated +resources are correctly freed. + +Fixes: 1f2acc5a8a0a ("MIPS: ralink: Add support for systick timer found on newer ralink SoC") +Signed-off-by: Haotian Zhang +Signed-off-by: Daniel Lezcano +Link: https://patch.msgid.link/20251030090710.1603-1-vulab@iscas.ac.cn +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-ralink.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clocksource/timer-ralink.c b/drivers/clocksource/timer-ralink.c +index 6ecdb4228f763..68434d9ed9107 100644 +--- a/drivers/clocksource/timer-ralink.c ++++ b/drivers/clocksource/timer-ralink.c +@@ -130,14 +130,15 @@ static int __init ralink_systick_init(struct device_node *np) + systick.dev.irq = irq_of_parse_and_map(np, 0); + if (!systick.dev.irq) { + pr_err("%pOFn: request_irq failed", np); +- return -EINVAL; ++ ret = -EINVAL; ++ goto err_iounmap; + } + + ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name, + SYSTICK_FREQ, 301, 16, + clocksource_mmio_readl_up); + if (ret) +- return ret; ++ goto err_free_irq; + + clockevents_register_device(&systick.dev); + +@@ -145,6 +146,12 @@ static int __init ralink_systick_init(struct device_node *np) + np, systick.dev.mult, systick.dev.shift); + + return 0; ++ ++err_free_irq: ++ irq_dispose_mapping(systick.dev.irq); ++err_iounmap: ++ iounmap(systick.membase); ++ return ret; + } + + TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init); +-- +2.51.0 + diff --git a/queue-6.18/clocksource-drivers-stm-fix-double-deregistration-on.patch b/queue-6.18/clocksource-drivers-stm-fix-double-deregistration-on.patch new file mode 100644 index 0000000000..ddea586de2 --- /dev/null +++ b/queue-6.18/clocksource-drivers-stm-fix-double-deregistration-on.patch @@ -0,0 +1,42 @@ +From 5596bdf7f0ed48cd3f92a30002e90e7a90fb09b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 07:50:39 +0200 +Subject: clocksource/drivers/stm: Fix double deregistration on probe failure + +From: Johan Hovold + +[ Upstream commit 6b38a8b31e2c5c2c3fd5f9848850788c190f216d ] + +The purpose of the devm_add_action_or_reset() helper is to call the +action function in case adding an action ever fails so drop the clock +source deregistration from the error path to avoid deregistering twice. + +Fixes: cec32ac75827 ("clocksource/drivers/nxp-timer: Add the System Timer Module for the s32gx platforms") +Signed-off-by: Johan Hovold +Signed-off-by: Daniel Lezcano +Cc: Daniel Lezcano +Link: https://patch.msgid.link/20251017055039.7307-1-johan@kernel.org +Signed-off-by: Sasha Levin +--- + drivers/clocksource/timer-nxp-stm.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/clocksource/timer-nxp-stm.c b/drivers/clocksource/timer-nxp-stm.c +index bbc40623728fa..16d52167e949b 100644 +--- a/drivers/clocksource/timer-nxp-stm.c ++++ b/drivers/clocksource/timer-nxp-stm.c +@@ -208,10 +208,8 @@ static int __init nxp_stm_clocksource_init(struct device *dev, struct stm_timer + return ret; + + ret = devm_add_action_or_reset(dev, devm_clocksource_unregister, stm_timer); +- if (ret) { +- clocksource_unregister(&stm_timer->cs); ++ if (ret) + return ret; +- } + + stm_sched_clock = stm_timer; + +-- +2.51.0 + diff --git a/queue-6.18/coresight-change-device-mode-to-atomic-type.patch b/queue-6.18/coresight-change-device-mode-to-atomic-type.patch new file mode 100644 index 0000000000..557364f04a --- /dev/null +++ b/queue-6.18/coresight-change-device-mode-to-atomic-type.patch @@ -0,0 +1,91 @@ +From c26910092977d60d1ccbc7a2731fb31a1cdb002c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:35 +0000 +Subject: coresight: Change device mode to atomic type + +From: Leo Yan + +[ Upstream commit 693d1eaca940f277af24c74873ef2313816ff444 ] + +The device mode is defined as local type. This type cannot promise +SMP-safe access. + +Change to atomic type and impose relax ordering, which ensures the +SMP-safe synchronisation and the ordering between the mode setting and +relevant operations. + +Fixes: 22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()") +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-1-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + include/linux/coresight.h | 25 +++++++++++-------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index 2626105e37191..fafc9ec13f9f4 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -251,15 +251,11 @@ struct coresight_trace_id_map { + * by @coresight_ops. + * @access: Device i/o access abstraction for this device. + * @dev: The device entity associated to this component. +- * @mode: This tracer's mode, i.e sysFS, Perf or disabled. This is +- * actually an 'enum cs_mode', but is stored in an atomic type. +- * This is always accessed through local_read() and local_set(), +- * but wherever it's done from within the Coresight device's lock, +- * a non-atomic read would also work. This is the main point of +- * synchronisation between code happening inside the sysfs mode's +- * coresight_mutex and outside when running in Perf mode. A compare +- * and exchange swap is done to atomically claim one mode or the +- * other. ++ * @mode: The device mode, i.e sysFS, Perf or disabled. This is actually ++ * an 'enum cs_mode' but stored in an atomic type. Access is always ++ * through atomic APIs, ensuring SMP-safe synchronisation between ++ * racing from sysFS and Perf mode. A compare-and-exchange ++ * operation is done to atomically claim one mode or the other. + * @refcnt: keep track of what is in use. Only access this outside of the + * device's spinlock when the coresight_mutex held and mode == + * CS_MODE_SYSFS. Otherwise it must be accessed from inside the +@@ -288,7 +284,7 @@ struct coresight_device { + const struct coresight_ops *ops; + struct csdev_access access; + struct device dev; +- local_t mode; ++ atomic_t mode; + int refcnt; + bool orphan; + /* sink specific fields */ +@@ -623,13 +619,14 @@ static inline bool coresight_is_percpu_sink(struct coresight_device *csdev) + static inline bool coresight_take_mode(struct coresight_device *csdev, + enum cs_mode new_mode) + { +- return local_cmpxchg(&csdev->mode, CS_MODE_DISABLED, new_mode) == +- CS_MODE_DISABLED; ++ int curr = CS_MODE_DISABLED; ++ ++ return atomic_try_cmpxchg_acquire(&csdev->mode, &curr, new_mode); + } + + static inline enum cs_mode coresight_get_mode(struct coresight_device *csdev) + { +- return local_read(&csdev->mode); ++ return atomic_read_acquire(&csdev->mode); + } + + static inline void coresight_set_mode(struct coresight_device *csdev, +@@ -645,7 +642,7 @@ static inline void coresight_set_mode(struct coresight_device *csdev, + WARN(new_mode != CS_MODE_DISABLED && current_mode != CS_MODE_DISABLED && + current_mode != new_mode, "Device already in use\n"); + +- local_set(&csdev->mode, new_mode); ++ atomic_set_release(&csdev->mode, new_mode); + } + + struct coresight_device *coresight_register(struct coresight_desc *desc); +-- +2.51.0 + diff --git a/queue-6.18/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch b/queue-6.18/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch new file mode 100644 index 0000000000..1dbb4f64fb --- /dev/null +++ b/queue-6.18/coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch @@ -0,0 +1,176 @@ +From 577d3724ccd5cd626d68bf2fa15ddbdd397bfac4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:37 +0000 +Subject: coresight: etm3x: Always set tracer's device mode on target CPU + +From: Leo Yan + +[ Upstream commit ab3fde32afe6a77e5cc60f868e44e6e09424752b ] + +The ETMv3 driver shares the same issue as ETMv4 regarding race +conditions when accessing the device mode. + +This commit applies the same fix: ensuring that the device mode is +modified only by the target CPU to eliminate race conditions across +CPUs. + +Fixes: 22fd532eaa0c ("coresight: etm3x: adding operation mode for etm_enable()") +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-3-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm3x-core.c | 59 +++++++++++++------ + 1 file changed, 40 insertions(+), 19 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm3x-core.c b/drivers/hwtracing/coresight/coresight-etm3x-core.c +index 45630a1cd32fb..a5e809589d3e3 100644 +--- a/drivers/hwtracing/coresight/coresight-etm3x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm3x-core.c +@@ -439,13 +439,26 @@ struct etm_enable_arg { + int rc; + }; + +-static void etm_enable_hw_smp_call(void *info) ++static void etm_enable_sysfs_smp_call(void *info) + { + struct etm_enable_arg *arg = info; ++ struct coresight_device *csdev; + + if (WARN_ON(!arg)) + return; ++ ++ csdev = arg->drvdata->csdev; ++ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) { ++ /* Someone is already using the tracer */ ++ arg->rc = -EBUSY; ++ return; ++ } ++ + arg->rc = etm_enable_hw(arg->drvdata); ++ ++ /* The tracer didn't start */ ++ if (arg->rc) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static int etm_cpu_id(struct coresight_device *csdev) +@@ -465,16 +478,26 @@ static int etm_enable_perf(struct coresight_device *csdev, + struct coresight_path *path) + { + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); ++ int ret; + + if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) + return -EINVAL; + ++ if (!coresight_take_mode(csdev, CS_MODE_PERF)) ++ return -EBUSY; ++ + /* Configure the tracer based on the session's specifics */ + etm_parse_event_config(drvdata, event); + drvdata->traceid = path->trace_id; + + /* And enable it */ +- return etm_enable_hw(drvdata); ++ ret = etm_enable_hw(drvdata); ++ ++ /* Failed to start tracer; roll back to DISABLED mode */ ++ if (ret) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); ++ ++ return ret; + } + + static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_path *path) +@@ -494,7 +517,7 @@ static int etm_enable_sysfs(struct coresight_device *csdev, struct coresight_pat + if (cpu_online(drvdata->cpu)) { + arg.drvdata = drvdata; + ret = smp_call_function_single(drvdata->cpu, +- etm_enable_hw_smp_call, &arg, 1); ++ etm_enable_sysfs_smp_call, &arg, 1); + if (!ret) + ret = arg.rc; + if (!ret) +@@ -517,12 +540,6 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event, + enum cs_mode mode, struct coresight_path *path) + { + int ret; +- struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); +- +- if (!coresight_take_mode(csdev, mode)) { +- /* Someone is already using the tracer */ +- return -EBUSY; +- } + + switch (mode) { + case CS_MODE_SYSFS: +@@ -535,17 +552,12 @@ static int etm_enable(struct coresight_device *csdev, struct perf_event *event, + ret = -EINVAL; + } + +- /* The tracer didn't start */ +- if (ret) +- coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); +- + return ret; + } + +-static void etm_disable_hw(void *info) ++static void etm_disable_hw(struct etm_drvdata *drvdata) + { + int i; +- struct etm_drvdata *drvdata = info; + struct etm_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + +@@ -567,6 +579,15 @@ static void etm_disable_hw(void *info) + "cpu: %d disable smp call done\n", drvdata->cpu); + } + ++static void etm_disable_sysfs_smp_call(void *info) ++{ ++ struct etm_drvdata *drvdata = info; ++ ++ etm_disable_hw(drvdata); ++ ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++} ++ + static void etm_disable_perf(struct coresight_device *csdev) + { + struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); +@@ -588,6 +609,8 @@ static void etm_disable_perf(struct coresight_device *csdev) + + CS_LOCK(drvdata->csa.base); + ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++ + /* + * perf will release trace ids when _free_aux() + * is called at the end of the session +@@ -612,7 +635,8 @@ static void etm_disable_sysfs(struct coresight_device *csdev) + * Executing etm_disable_hw on the cpu whose ETM is being disabled + * ensures that register writes occur when cpu is powered. + */ +- smp_call_function_single(drvdata->cpu, etm_disable_hw, drvdata, 1); ++ smp_call_function_single(drvdata->cpu, etm_disable_sysfs_smp_call, ++ drvdata, 1); + + spin_unlock(&drvdata->spinlock); + cpus_read_unlock(); +@@ -652,9 +676,6 @@ static void etm_disable(struct coresight_device *csdev, + WARN_ON_ONCE(mode); + return; + } +- +- if (mode) +- coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static const struct coresight_ops_source etm_source_ops = { +-- +2.51.0 + diff --git a/queue-6.18/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-6.18/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..42a9bbed33 --- /dev/null +++ b/queue-6.18/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From bf41872477d39f8fa3fc186b10866eab0b68e0d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index c562f82985192..5e707d082537a 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -446,10 +446,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -931,11 +945,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-6.18/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch b/queue-6.18/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch new file mode 100644 index 0000000000..a2c434cbc8 --- /dev/null +++ b/queue-6.18/coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch @@ -0,0 +1,230 @@ +From 67b038e9861aac6b5ccc4091463991dd6f8363cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:36 +0000 +Subject: coresight: etm4x: Always set tracer's device mode on target CPU + +From: Leo Yan + +[ Upstream commit 28eee2158575aea8fee7807adb9248ceaf9196f1 ] + +When enabling a tracer via SysFS interface, the device mode may be set +by any CPU - not necessarily the target CPU. This can lead to race +condition in SMP, and may result in incorrect mode values being read. + +Consider the following example, where CPU0 attempts to enable the tracer +on CPU1 (the target CPU): + + CPU0 CPU1 + etm4_enable() + ` coresight_take_mode(SYSFS) + ` etm4_enable_sysfs() + ` smp_call_function_single() ----> etm4_enable_hw_smp_call() + / + / CPU idle: + / etm4_cpu_save() + / ` coresight_get_mode() + Failed to enable h/w / ^^^ + ` coresight_set_mode(DISABLED) <-' Read the intermediate SYSFS mode + +In this case, CPU0 initiates the operation by taking the SYSFS mode to +avoid conflicts with the Perf mode. It then sends an IPI to CPU1 to +configure the tracer registers. If any error occurs during this process, +CPU0 rolls back by setting the mode to DISABLED. + +However, if CPU1 enters an idle state during this time, it might read +the intermediate SYSFS mode. As a result, the CPU PM flow could wrongly +save and restore tracer context that is actually disabled. + +To resolve the issue, this commit moves the device mode setting logic on +the target CPU. This ensures that the device mode is only modified by +the target CPU, eliminating race condition between mode writes and reads +across CPUs. + +An additional change introduces the etm4_disable_sysfs_smp_call() +function for SMP calls, which disables the tracer and explicitly set the +mode to DISABLED during SysFS operations. Rename +etm4_disable_hw_smp_call() to etm4_disable_sysfs_smp_call() for naming +consistency. + +The flow is updated with this change: + + CPU0 CPU1 + etm4_enable() + ` etm4_enable_sysfs() + ` smp_call_function_single() ----> etm4_enable_hw_smp_call() + ` coresight_take_mode(SYSFS) + Failed, set back to DISABLED + ` coresight_set_mode(DISABLED) + + CPU idle: + etm4_cpu_save() + ` coresight_get_mode() + ^^^ + Read out the DISABLED mode + +Fixes: c38a9ec2b2c1 ("coresight: etm4x: moving etm_drvdata::enable to atomic field") +Reviewed-by: Yeoreum Yun +Reviewed-by: mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-2-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 60 ++++++++++++------- + 1 file changed, 38 insertions(+), 22 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 020f070bf17dc..1324b40d54210 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -589,13 +589,26 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + return rc; + } + +-static void etm4_enable_hw_smp_call(void *info) ++static void etm4_enable_sysfs_smp_call(void *info) + { + struct etm4_enable_arg *arg = info; ++ struct coresight_device *csdev; + + if (WARN_ON(!arg)) + return; ++ ++ csdev = arg->drvdata->csdev; ++ if (!coresight_take_mode(csdev, CS_MODE_SYSFS)) { ++ /* Someone is already using the tracer */ ++ arg->rc = -EBUSY; ++ return; ++ } ++ + arg->rc = etm4_enable_hw(arg->drvdata); ++ ++ /* The tracer didn't start */ ++ if (arg->rc) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + /* +@@ -808,13 +821,14 @@ static int etm4_enable_perf(struct coresight_device *csdev, + struct perf_event *event, + struct coresight_path *path) + { +- int ret = 0; + struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); ++ int ret; + +- if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) { +- ret = -EINVAL; +- goto out; +- } ++ if (WARN_ON_ONCE(drvdata->cpu != smp_processor_id())) ++ return -EINVAL; ++ ++ if (!coresight_take_mode(csdev, CS_MODE_PERF)) ++ return -EBUSY; + + /* Configure the tracer based on the session's specifics */ + ret = etm4_parse_event_config(csdev, event); +@@ -830,6 +844,9 @@ static int etm4_enable_perf(struct coresight_device *csdev, + ret = etm4_enable_hw(drvdata); + + out: ++ /* Failed to start tracer; roll back to DISABLED mode */ ++ if (ret) ++ coresight_set_mode(csdev, CS_MODE_DISABLED); + return ret; + } + +@@ -861,7 +878,7 @@ static int etm4_enable_sysfs(struct coresight_device *csdev, struct coresight_pa + */ + arg.drvdata = drvdata; + ret = smp_call_function_single(drvdata->cpu, +- etm4_enable_hw_smp_call, &arg, 1); ++ etm4_enable_sysfs_smp_call, &arg, 1); + if (!ret) + ret = arg.rc; + if (!ret) +@@ -882,11 +899,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + { + int ret; + +- if (!coresight_take_mode(csdev, mode)) { +- /* Someone is already using the tracer */ +- return -EBUSY; +- } +- + switch (mode) { + case CS_MODE_SYSFS: + ret = etm4_enable_sysfs(csdev, path); +@@ -898,10 +910,6 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + ret = -EINVAL; + } + +- /* The tracer didn't start */ +- if (ret) +- coresight_set_mode(csdev, CS_MODE_DISABLED); +- + return ret; + } + +@@ -953,10 +961,9 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + isb(); + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_hw(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; + struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct csdev_access *csa = &csdev->access; +@@ -993,6 +1000,15 @@ static void etm4_disable_hw(void *info) + "cpu: %d disable smp call done\n", drvdata->cpu); + } + ++static void etm4_disable_sysfs_smp_call(void *info) ++{ ++ struct etmv4_drvdata *drvdata = info; ++ ++ etm4_disable_hw(drvdata); ++ ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++} ++ + static int etm4_disable_perf(struct coresight_device *csdev, + struct perf_event *event) + { +@@ -1022,6 +1038,8 @@ static int etm4_disable_perf(struct coresight_device *csdev, + /* TRCVICTLR::SSSTATUS, bit[9] */ + filters->ssstatus = (control & BIT(9)); + ++ coresight_set_mode(drvdata->csdev, CS_MODE_DISABLED); ++ + /* + * perf will release trace ids when _free_aux() is + * called at the end of the session. +@@ -1047,7 +1065,8 @@ static void etm4_disable_sysfs(struct coresight_device *csdev) + * Executing etm4_disable_hw on the cpu whose ETM is being disabled + * ensures that register writes occur when cpu is powered. + */ +- smp_call_function_single(drvdata->cpu, etm4_disable_hw, drvdata, 1); ++ smp_call_function_single(drvdata->cpu, etm4_disable_sysfs_smp_call, ++ drvdata, 1); + + raw_spin_unlock(&drvdata->spinlock); + +@@ -1087,9 +1106,6 @@ static void etm4_disable(struct coresight_device *csdev, + etm4_disable_perf(csdev, event); + break; + } +- +- if (mode) +- coresight_set_mode(csdev, CS_MODE_DISABLED); + } + + static int etm4_resume_perf(struct coresight_device *csdev) +-- +2.51.0 + diff --git a/queue-6.18/coresight-etm4x-correct-polling-idle-bit.patch b/queue-6.18/coresight-etm4x-correct-polling-idle-bit.patch new file mode 100644 index 0000000000..1ba8985bf9 --- /dev/null +++ b/queue-6.18/coresight-etm4x-correct-polling-idle-bit.patch @@ -0,0 +1,43 @@ +From 0c44f55b85fadcf0328137c1bdbd001a5145a149 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:38 +0000 +Subject: coresight: etm4x: Correct polling IDLE bit + +From: Leo Yan + +[ Upstream commit 4dc4e22f9536341255f5de6047977a80ff47eaef ] + +Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading +the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit +instead of the IDLE bit. + +This commit corrects the typo. + +Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") +Reviewed-by: Yeoreum Yun +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 1324b40d54210..c562f82985192 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1924,7 +1924,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +-- +2.51.0 + diff --git a/queue-6.18/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch b/queue-6.18/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch new file mode 100644 index 0000000000..5fc3920201 --- /dev/null +++ b/queue-6.18/coresight-etm4x-properly-control-filter-in-cpu-idle-.patch @@ -0,0 +1,125 @@ +From ffbd4f05dfef7bbf22711e73cba19df8dd8b5588 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:40 +0000 +Subject: coresight: etm4x: Properly control filter in CPU idle with FEAT_TRF + +From: Leo Yan + +[ Upstream commit 1fdc2cd347a7bc58acacb6144404ee892cea6c2e ] + +If a CPU supports FEAT_TRF, as described in the section K5.5 "Context +switching", Arm ARM (ARM DDI 0487 L.a), it defines a flow to prohibit +program-flow trace, execute a TSB CSYNC instruction for flushing, +followed by clearing TRCPRGCTLR.EN bit. + +To restore the state, the reverse sequence is required. + +This differs from the procedure described in the section 3.4.1 "The +procedure when powering down the PE" of ARM IHI0064H.b, which involves +the OS Lock to prevent external debugger accesses and implicitly +disables trace. + +To be compatible with different ETM versions, explicitly control trace +unit using etm4_disable_trace_unit() and etm4_enable_trace_unit() +during CPU idle to comply with FEAT_TRF. + +As a result, the save states for TRFCR_ELx and trcprgctlr are redundant, +remove them. + +Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states") +Reviewed-by: Mike Leach +Tested-by: James Clark +Reviewed-by: Yeoreum Yun +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-6-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 14 +++++++------- + drivers/hwtracing/coresight/coresight-etm4x.h | 3 --- + 2 files changed, 7 insertions(+), 10 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index 5e707d082537a..fdda924a2c711 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1858,9 +1858,11 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + goto out; + } + ++ if (!drvdata->paused) ++ etm4_disable_trace_unit(drvdata); ++ + state = drvdata->save_state; + +- state->trcprgctlr = etm4x_read32(csa, TRCPRGCTLR); + if (drvdata->nr_pe) + state->trcprocselr = etm4x_read32(csa, TRCPROCSELR); + state->trcconfigr = etm4x_read32(csa, TRCCONFIGR); +@@ -1970,9 +1972,6 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata) + { + int ret = 0; + +- /* Save the TRFCR irrespective of whether the ETM is ON */ +- if (drvdata->trfcr) +- drvdata->save_trfcr = read_trfcr(); + /* + * Save and restore the ETM Trace registers only if + * the ETM is active. +@@ -1994,7 +1993,6 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + etm4_cs_unlock(drvdata, csa); + etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET); + +- etm4x_relaxed_write32(csa, state->trcprgctlr, TRCPRGCTLR); + if (drvdata->nr_pe) + etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR); + etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR); +@@ -2079,13 +2077,15 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata) + + /* Unlock the OS lock to re-enable trace and external debug access */ + etm4_os_unlock(drvdata); ++ ++ if (!drvdata->paused) ++ etm4_enable_trace_unit(drvdata); ++ + etm4_cs_lock(drvdata, csa); + } + + static void etm4_cpu_restore(struct etmv4_drvdata *drvdata) + { +- if (drvdata->trfcr) +- write_trfcr(drvdata->save_trfcr); + if (drvdata->state_needs_restore) + __etm4_cpu_restore(drvdata); + } +diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h +index 13ec9ecef46f5..b8796b4271025 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x.h ++++ b/drivers/hwtracing/coresight/coresight-etm4x.h +@@ -866,7 +866,6 @@ struct etmv4_config { + * struct etm4_save_state - state to be preserved when ETM is without power + */ + struct etmv4_save_state { +- u32 trcprgctlr; + u32 trcprocselr; + u32 trcconfigr; + u32 trcauxctlr; +@@ -980,7 +979,6 @@ struct etmv4_save_state { + * at runtime, due to the additional setting of TRFCR_CX when + * in EL2. Otherwise, 0. + * @config: structure holding configuration parameters. +- * @save_trfcr: Saved TRFCR_EL1 register during a CPU PM event. + * @save_state: State to be preserved across power loss + * @state_needs_restore: True when there is context to restore after PM exit + * @skip_power_up: Indicates if an implementation can skip powering up +@@ -1037,7 +1035,6 @@ struct etmv4_drvdata { + bool lpoverride; + u64 trfcr; + struct etmv4_config config; +- u64 save_trfcr; + struct etmv4_save_state *save_state; + bool state_needs_restore; + bool skip_power_up; +-- +2.51.0 + diff --git a/queue-6.18/coresight-etr-fix-etr-buffer-use-after-free-issue.patch b/queue-6.18/coresight-etr-fix-etr-buffer-use-after-free-issue.patch new file mode 100644 index 0000000000..774147842d --- /dev/null +++ b/queue-6.18/coresight-etr-fix-etr-buffer-use-after-free-issue.patch @@ -0,0 +1,50 @@ +From 4e54ca2fc832e61daf38ad79f372099046c52a2f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 16:45:25 +0800 +Subject: coresight: ETR: Fix ETR buffer use-after-free issue + +From: Xiaoqi Zhuang + +[ Upstream commit 35501ac3c7d40a7bb9568c2f89d6b56beaf9bed3 ] + +When ETR is enabled as CS_MODE_SYSFS, if the buffer size is changed +and enabled again, currently sysfs_buf will point to the newly +allocated memory(buf_new) and free the old memory(buf_old). But the +etr_buf that is being used by the ETR remains pointed to buf_old, not +updated to buf_new. In this case, it will result in a memory +use-after-free issue. + +Fix this by checking ETR's mode before updating and releasing buf_old, +if the mode is CS_MODE_SYSFS, then skip updating and releasing it. + +Fixes: bd2767ec3df2 ("coresight: Fix run time warnings while reusing ETR buffer") +Signed-off-by: Xiaoqi Zhuang +Signed-off-by: Suzuki K Poulose +Tested-by: Leo Yan +Link: https://lore.kernel.org/r/20251021-fix_etr_issue-v3-1-99a2d066fee2@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-tmc-etr.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c +index b07fcdb3fe1a8..800be06598c1b 100644 +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1250,6 +1250,13 @@ static struct etr_buf *tmc_etr_get_sysfs_buffer(struct coresight_device *csdev) + * with the lock released. + */ + raw_spin_lock_irqsave(&drvdata->spinlock, flags); ++ ++ /* ++ * If the ETR is already enabled, continue with the existing buffer. ++ */ ++ if (coresight_get_mode(csdev) == CS_MODE_SYSFS) ++ goto out; ++ + sysfs_buf = READ_ONCE(drvdata->sysfs_buf); + if (!sysfs_buf || (sysfs_buf->size != drvdata->size)) { + raw_spin_unlock_irqrestore(&drvdata->spinlock, flags); +-- +2.51.0 + diff --git a/queue-6.18/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch b/queue-6.18/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch new file mode 100644 index 0000000000..966ef42873 --- /dev/null +++ b/queue-6.18/coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch @@ -0,0 +1,91 @@ +From 02ca4695366be255c682cc5af84314614bf8cf91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 18:42:31 +0800 +Subject: coresight: tmc: add the handle of the event to the path + +From: Carl Worth + +[ Upstream commit aaa5abcc9d44d2c8484f779ab46d242d774cabcb ] + +The handle is essential for retrieving the AUX_EVENT of each CPU and is +required in perf mode. It has been added to the coresight_path so that +dependent devices can access it from the path when needed. + +The existing bug can be reproduced with: +perf record -e cs_etm//k -C 0-9 dd if=/dev/zero of=/dev/null + +Showing an oops as follows: +Unable to handle kernel paging request at virtual address 000f6e84934ed19e + +Call trace: + tmc_etr_get_buffer+0x30/0x80 [coresight_tmc] (P) + catu_enable_hw+0xbc/0x3d0 [coresight_catu] + catu_enable+0x70/0xe0 [coresight_catu] + coresight_enable_path+0xb0/0x258 [coresight] + +Fixes: 080ee83cc361 ("Coresight: Change functions to accept the coresight_path") +Signed-off-by: Carl Worth +Reviewed-by: Leo Yan +Co-developed-by: Jie Gan +Signed-off-by: Jie Gan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250925-fix_helper_data-v2-1-edd8a07c1646@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm-perf.c | 1 + + drivers/hwtracing/coresight/coresight-tmc-etr.c | 3 ++- + include/linux/coresight.h | 10 ++++++---- + 3 files changed, 9 insertions(+), 5 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c +index f677c08233ba1..5c256af6e54af 100644 +--- a/drivers/hwtracing/coresight/coresight-etm-perf.c ++++ b/drivers/hwtracing/coresight/coresight-etm-perf.c +@@ -520,6 +520,7 @@ static void etm_event_start(struct perf_event *event, int flags) + goto out; + + path = etm_event_cpu_path(event_data, cpu); ++ path->handle = handle; + /* We need a sink, no need to continue without one */ + sink = coresight_get_sink(path); + if (WARN_ON_ONCE(!sink)) +diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c +index 800be06598c1b..60b0e0a6da057 100644 +--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c ++++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c +@@ -1334,7 +1334,8 @@ static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev) + struct etr_buf *tmc_etr_get_buffer(struct coresight_device *csdev, + enum cs_mode mode, void *data) + { +- struct perf_output_handle *handle = data; ++ struct coresight_path *path = data; ++ struct perf_output_handle *handle = path->handle; + struct etr_perf_buffer *etr_perf; + + switch (mode) { +diff --git a/include/linux/coresight.h b/include/linux/coresight.h +index 6de59ce8ef8ca..2626105e37191 100644 +--- a/include/linux/coresight.h ++++ b/include/linux/coresight.h +@@ -332,12 +332,14 @@ static struct coresight_dev_list (var) = { \ + + /** + * struct coresight_path - data needed by enable/disable path +- * @path_list: path from source to sink. +- * @trace_id: trace_id of the whole path. ++ * @path_list: path from source to sink. ++ * @trace_id: trace_id of the whole path. ++ * @handle: handle of the aux_event. + */ + struct coresight_path { +- struct list_head path_list; +- u8 trace_id; ++ struct list_head path_list; ++ u8 trace_id; ++ struct perf_output_handle *handle; + }; + + enum cs_mode { +-- +2.51.0 + diff --git a/queue-6.18/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch b/queue-6.18/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch new file mode 100644 index 0000000000..3a2f645caa --- /dev/null +++ b/queue-6.18/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch @@ -0,0 +1,44 @@ +From 2132232dab9a8818f5493614c7ffe916c73ee7e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 13:11:45 +0530 +Subject: cpufreq/amd-pstate: Call cppc_set_auto_sel() only for online CPUs + +From: Gautham R. Shenoy + +[ Upstream commit bb31fef0d03ed17d587b40e3458786be408fb9df ] + +amd_pstate_change_mode_without_dvr_change() calls cppc_set_auto_sel() +for all the present CPUs. + +However, this callpath eventually calls cppc_set_reg_val() which +accesses the per-cpu cpc_desc_ptr object. This object is initialized +only for online CPUs via acpi_soft_cpu_online() --> +__acpi_processor_start() --> acpi_cppc_processor_probe(). + +Hence, restrict calling cppc_set_auto_sel() to only the online CPUs. + +Fixes: 3ca7bc818d8c ("cpufreq: amd-pstate: Add guided mode control support via sysfs") +Suggested-by: Mario Limonciello (AMD) (kernel.org) +Signed-off-by: Gautham R. Shenoy +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd-pstate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index b44f0f7a5ba1c..602e4fa81d6c5 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -1282,7 +1282,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode) + if (cpu_feature_enabled(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE) + return 0; + +- for_each_present_cpu(cpu) { ++ for_each_online_cpu(cpu) { + cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1); + } + +-- +2.51.0 + diff --git a/queue-6.18/cpuset-treat-cpusets-in-attaching-as-populated.patch b/queue-6.18/cpuset-treat-cpusets-in-attaching-as-populated.patch new file mode 100644 index 0000000000..5fafe8f35b --- /dev/null +++ b/queue-6.18/cpuset-treat-cpusets-in-attaching-as-populated.patch @@ -0,0 +1,115 @@ +From d415758bb15f3e1c44aba8b2fb53b9fac81b6fb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 02:08:47 +0000 +Subject: cpuset: Treat cpusets in attaching as populated + +From: Chen Ridong + +[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ] + +Currently, the check for whether a partition is populated does not +account for tasks in the cpuset of attaching. This is a corner case +that can leave a task stuck in a partition with no effective CPUs. + +The race condition occurs as follows: + +cpu0 cpu1 + //cpuset A with cpu N +migrate task p to A +cpuset_can_attach +// with effective cpus +// check ok + +// cpuset_mutex is not held // clear cpuset.cpus.exclusive + // making effective cpus empty + update_exclusive_cpumask + // tasks_nocpu_error check ok + // empty effective cpus, partition valid +cpuset_attach +... +// task p stays in A, with non-effective cpus. + +To fix this issue, this patch introduces cs_is_populated, which considers +tasks in the attaching cpuset. This new helper is used in validate_change +and partition_is_populated. + +Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") +Signed-off-by: Chen Ridong +Reviewed-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index 52468d2c178a3..4dcd633fd6df5 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -352,6 +352,15 @@ static inline bool is_in_v2_mode(void) + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); + } + ++static inline bool cpuset_is_populated(struct cpuset *cs) ++{ ++ lockdep_assert_held(&cpuset_mutex); ++ ++ /* Cpusets in the process of attaching should be considered as populated */ ++ return cgroup_is_populated(cs->css.cgroup) || ++ cs->attach_in_progress; ++} ++ + /** + * partition_is_populated - check if partition has tasks + * @cs: partition root to be checked +@@ -364,21 +373,31 @@ static inline bool is_in_v2_mode(void) + static inline bool partition_is_populated(struct cpuset *cs, + struct cpuset *excluded_child) + { +- struct cgroup_subsys_state *css; +- struct cpuset *child; ++ struct cpuset *cp; ++ struct cgroup_subsys_state *pos_css; + +- if (cs->css.cgroup->nr_populated_csets) ++ /* ++ * We cannot call cs_is_populated(cs) directly, as ++ * nr_populated_domain_children may include populated ++ * csets from descendants that are partitions. ++ */ ++ if (cs->css.cgroup->nr_populated_csets || ++ cs->attach_in_progress) + return true; + if (!excluded_child && !cs->nr_subparts) + return cgroup_is_populated(cs->css.cgroup); + + rcu_read_lock(); +- cpuset_for_each_child(child, css, cs) { +- if (child == excluded_child) ++ cpuset_for_each_descendant_pre(cp, pos_css, cs) { ++ if (cp == cs || cp == excluded_child) + continue; +- if (is_partition_valid(child)) ++ ++ if (is_partition_valid(cp)) { ++ pos_css = css_rightmost_descendant(pos_css); + continue; +- if (cgroup_is_populated(child->css.cgroup)) { ++ } ++ ++ if (cpuset_is_populated(cp)) { + rcu_read_unlock(); + return true; + } +@@ -663,7 +682,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) + * be changed to have empty cpus_allowed or mems_allowed. + */ + ret = -ENOSPC; +- if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { ++ if (cpuset_is_populated(cur)) { + if (!cpumask_empty(cur->cpus_allowed) && + cpumask_empty(trial->cpus_allowed)) + goto out; +-- +2.51.0 + diff --git a/queue-6.18/crypto-aead-fix-reqsize-handling.patch b/queue-6.18/crypto-aead-fix-reqsize-handling.patch new file mode 100644 index 0000000000..19c891b645 --- /dev/null +++ b/queue-6.18/crypto-aead-fix-reqsize-handling.patch @@ -0,0 +1,49 @@ +From 4f7ad484bba66169096d4107a77e34cb6695cabd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:03:14 +0530 +Subject: crypto: aead - Fix reqsize handling + +From: T Pratham + +[ Upstream commit 9b04d8f00569573796dd05397f5779135593eb24 ] + +Commit afddce13ce81d ("crypto: api - Add reqsize to crypto_alg") +introduced cra_reqsize field in crypto_alg struct to replace type +specific reqsize fields. It looks like this was introduced specifically +for ahash and acomp from the commit description as subsequent commits +add necessary changes in these alg frameworks. + +However, this is being recommended for use in all crypto algs +instead of setting reqsize using crypto_*_set_reqsize(). Using +cra_reqsize in aead algorithms, hence, causes memory corruptions and +crashes as the underlying functions in the algorithm framework have not +been updated to set the reqsize properly from cra_reqsize. [1] + +Add proper set_reqsize calls in the aead init function to properly +initialize reqsize for these algorithms in the framework. + +[1]: https://gist.github.com/Pratham-T/24247446f1faf4b7843e4014d5089f6b + +Fixes: afddce13ce81d ("crypto: api - Add reqsize to crypto_alg") +Signed-off-by: T Pratham +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/aead.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/crypto/aead.c b/crypto/aead.c +index 5d14b775036ee..51ab3af691af2 100644 +--- a/crypto/aead.c ++++ b/crypto/aead.c +@@ -120,6 +120,7 @@ static int crypto_aead_init_tfm(struct crypto_tfm *tfm) + struct aead_alg *alg = crypto_aead_alg(aead); + + crypto_aead_set_flags(aead, CRYPTO_TFM_NEED_KEY); ++ crypto_aead_set_reqsize(aead, crypto_tfm_alg_reqsize(tfm)); + + aead->authsize = alg->maxauthsize; + +-- +2.51.0 + diff --git a/queue-6.18/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch b/queue-6.18/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch new file mode 100644 index 0000000000..e4441dab8c --- /dev/null +++ b/queue-6.18/crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch @@ -0,0 +1,60 @@ +From 33554cf1d89dc6e93425b8af8ec6b77cec811cd4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 13:36:03 +0800 +Subject: crypto: ahash - Fix crypto_ahash_import with partial block data + +From: Herbert Xu + +[ Upstream commit b0356b75f42fde15d4be268c5891f2cee6eb65bf ] + +Restore the partial block buffer in crypto_ahash_import by copying +it. Check whether the partial block buffer exceeds the maximum +size and return -EOVERFLOW if it does. + +Zero the partial block buffer in crypto_ahash_import_core. + +Reported-by: T Pratham +Tested-by: T Pratham +Fixes: 9d7a0ab1c753 ("crypto: ahash - Handle partial blocks in API") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ahash.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index dfb4f5476428f..819b484a1a003 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -661,6 +661,12 @@ int crypto_ahash_import_core(struct ahash_request *req, const void *in) + in); + if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) + return -ENOKEY; ++ if (crypto_ahash_block_only(tfm)) { ++ unsigned int reqsize = crypto_ahash_reqsize(tfm); ++ u8 *buf = ahash_request_ctx(req); ++ ++ buf[reqsize - 1] = 0; ++ } + return crypto_ahash_alg(tfm)->import_core(req, in); + } + EXPORT_SYMBOL_GPL(crypto_ahash_import_core); +@@ -674,10 +680,14 @@ int crypto_ahash_import(struct ahash_request *req, const void *in) + if (crypto_ahash_get_flags(tfm) & CRYPTO_TFM_NEED_KEY) + return -ENOKEY; + if (crypto_ahash_block_only(tfm)) { ++ unsigned int plen = crypto_ahash_blocksize(tfm) + 1; + unsigned int reqsize = crypto_ahash_reqsize(tfm); ++ unsigned int ss = crypto_ahash_statesize(tfm); + u8 *buf = ahash_request_ctx(req); + +- buf[reqsize - 1] = 0; ++ memcpy(buf + reqsize - plen, in + ss - plen, plen); ++ if (buf[reqsize - 1] >= plen) ++ return -EOVERFLOW; + } + return crypto_ahash_alg(tfm)->import(req, in); + } +-- +2.51.0 + diff --git a/queue-6.18/crypto-ahash-zero-positive-err-value-in-ahash_update.patch b/queue-6.18/crypto-ahash-zero-positive-err-value-in-ahash_update.patch new file mode 100644 index 0000000000..4dab995102 --- /dev/null +++ b/queue-6.18/crypto-ahash-zero-positive-err-value-in-ahash_update.patch @@ -0,0 +1,44 @@ +From 9bbc248403b8e37b86c989d389454a06fac287a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 13:54:20 +0800 +Subject: crypto: ahash - Zero positive err value in ahash_update_finish + +From: Herbert Xu + +[ Upstream commit ebbdf6466b30e3b37f3b360826efd21f0633fb9e ] + +The partial block length returned by a block-only driver should +not be passed up to the caller since ahash itself deals with the +partial block data. + +Set err to zero in ahash_update_finish if it was positive. + +Reported-by: T Pratham +Tested-by: T Pratham +Fixes: 9d7a0ab1c753 ("crypto: ahash - Handle partial blocks in API") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/ahash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/crypto/ahash.c b/crypto/ahash.c +index 819b484a1a003..66492ae75fcfb 100644 +--- a/crypto/ahash.c ++++ b/crypto/ahash.c +@@ -423,7 +423,11 @@ static int ahash_update_finish(struct ahash_request *req, int err) + + req->nbytes += nonzero - blen; + +- blen = err < 0 ? 0 : err + nonzero; ++ blen = 0; ++ if (err >= 0) { ++ blen = err + nonzero; ++ err = 0; ++ } + if (ahash_request_isvirt(req)) + memcpy(buf, req->svirt + req->nbytes - blen, blen); + else +-- +2.51.0 + diff --git a/queue-6.18/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-6.18/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..9c6facb2ef --- /dev/null +++ b/queue-6.18/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From fcb6c89bfce06d5f70c787519dbafc4919c7bb8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index ba2d9d1ea235a..348966ea2175c 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -141,12 +142,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-6.18/crypto-authenc-correctly-pass-einprogress-back-up-to.patch b/queue-6.18/crypto-authenc-correctly-pass-einprogress-back-up-to.patch new file mode 100644 index 0000000000..403c604f90 --- /dev/null +++ b/queue-6.18/crypto-authenc-correctly-pass-einprogress-back-up-to.patch @@ -0,0 +1,202 @@ +From e45744d9fa225352b125069bdfbaf176d718a7e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 18:20:17 +0800 +Subject: crypto: authenc - Correctly pass EINPROGRESS back up to the caller + +From: Herbert Xu + +[ Upstream commit 96feb73def02d175850daa0e7c2c90c876681b5c ] + +When authenc is invoked with MAY_BACKLOG, it needs to pass EINPROGRESS +notifications back up to the caller when the underlying algorithm +returns EBUSY synchronously. + +However, if the EBUSY comes from the second part of an authenc call, +i.e., it is asynchronous, both the EBUSY and the subsequent EINPROGRESS +notification must not be passed to the caller. + +Implement this by passing a mask to the function that starts the +second half of authenc and using it to determine whether EBUSY +and EINPROGRESS should be passed to the caller. + +This was a deficiency in the original implementation of authenc +because it was not expected to be used with MAY_BACKLOG. + +Reported-by: Ingo Franzki +Reported-by: Mikulas Patocka +Fixes: 180ce7e81030 ("crypto: authenc - Add EINPROGRESS check") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/authenc.c | 75 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/crypto/authenc.c b/crypto/authenc.c +index a723769c87779..ac679ce2cb953 100644 +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -37,7 +37,7 @@ struct authenc_request_ctx { + + static void authenc_request_complete(struct aead_request *req, int err) + { +- if (err != -EINPROGRESS) ++ if (err != -EINPROGRESS && err != -EBUSY) + aead_request_complete(req, err); + } + +@@ -107,27 +107,42 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, + return err; + } + +-static void authenc_geniv_ahash_done(void *data, int err) ++static void authenc_geniv_ahash_finish(struct aead_request *req) + { +- struct aead_request *req = data; + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); + struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + +- if (err) +- goto out; +- + scatterwalk_map_and_copy(ahreq->result, req->dst, + req->assoclen + req->cryptlen, + crypto_aead_authsize(authenc), 1); ++} + +-out: ++static void authenc_geniv_ahash_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); + aead_request_complete(req, err); + } + +-static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ++/* ++ * Used when the ahash request was invoked in the async callback context ++ * of the previous skcipher request. Eat any EINPROGRESS notifications. ++ */ ++static void authenc_geniv_ahash_done2(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); ++ authenc_request_complete(req, err); ++} ++ ++static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -136,6 +151,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + struct crypto_ahash *auth = ctx->auth; + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *hash = areq_ctx->tail; + int err; + +@@ -143,7 +159,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + ahash_request_set_crypt(ahreq, req->dst, hash, + req->assoclen + req->cryptlen); + ahash_request_set_callback(ahreq, flags, +- authenc_geniv_ahash_done, req); ++ mask ? authenc_geniv_ahash_done2 : ++ authenc_geniv_ahash_done, req); + + err = crypto_ahash_digest(ahreq); + if (err) +@@ -159,12 +176,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) + { + struct aead_request *areq = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_genicv(areq, 0); +- +-out: ++ if (err) { ++ aead_request_complete(areq, err); ++ return; ++ } ++ err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(areq, err); + } + +@@ -199,11 +215,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_genicv(req, aead_request_flags(req)); ++ return crypto_authenc_genicv(req, 0); ++} ++ ++static void authenc_decrypt_tail_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ authenc_request_complete(req, err); + } + + static int crypto_authenc_decrypt_tail(struct aead_request *req, +- unsigned int flags) ++ unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -214,6 +237,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + struct skcipher_request *skreq = (void *)(areq_ctx->tail + + ictx->reqoff); + unsigned int authsize = crypto_aead_authsize(authenc); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *ihash = ahreq->result + authsize; + struct scatterlist *src, *dst; + +@@ -230,7 +254,9 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + + skcipher_request_set_tfm(skreq, ctx->enc); + skcipher_request_set_callback(skreq, flags, +- req->base.complete, req->base.data); ++ mask ? authenc_decrypt_tail_done : ++ req->base.complete, ++ mask ? req : req->base.data); + skcipher_request_set_crypt(skreq, src, dst, + req->cryptlen - authsize, req->iv); + +@@ -241,12 +267,11 @@ static void authenc_verify_ahash_done(void *data, int err) + { + struct aead_request *req = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_decrypt_tail(req, 0); +- +-out: ++ if (err) { ++ aead_request_complete(req, err); ++ return; ++ } ++ err = crypto_authenc_decrypt_tail(req, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(req, err); + } + +@@ -273,7 +298,7 @@ static int crypto_authenc_decrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); ++ return crypto_authenc_decrypt_tail(req, 0); + } + + static int crypto_authenc_init_tfm(struct crypto_aead *tfm) +-- +2.51.0 + diff --git a/queue-6.18/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-6.18/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..c48a5dda0c --- /dev/null +++ b/queue-6.18/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From 2a8489d43663a30d4c2672f4a352096f3a8d6e68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index 3963bb91321fc..dc7e0cd51c259 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%p curr_buff_cnt=0x%X nbytes=0x%X src=%p curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%p *curr_buff_cnt=0x%X copy_to=%p\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-6.18/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-6.18/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..b571b04c75 --- /dev/null +++ b/queue-6.18/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From ef73f9f890a4e9a4cda0b8f36ed1fecdd9ae8c8a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index 3b391a1466353..0968304c0cb51 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3678,6 +3678,7 @@ static void qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -3685,6 +3686,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -3698,11 +3700,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-6.18/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch b/queue-6.18/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch new file mode 100644 index 0000000000..50d9db39c7 --- /dev/null +++ b/queue-6.18/crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch @@ -0,0 +1,40 @@ +From f5df7c7ac3b511b72ee5d68b57b39f0542a50767 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 9 Nov 2025 14:56:48 +0000 +Subject: crypto: iaa - Fix incorrect return value in save_iaa_wq() + +From: Zilin Guan + +[ Upstream commit 76ce17f6f7f78ab79b9741388bdb4dafa985b4e9 ] + +The save_iaa_wq() function unconditionally returns 0, even when an error +is encountered. This prevents the error code from being propagated to the +caller. + +Fix this by returning the 'ret' variable, which holds the actual status +of the operations within the function. + +Fixes: ea7a5cbb43696 ("crypto: iaa - Add Intel IAA Compression Accelerator crypto driver core") +Signed-off-by: Zilin Guan +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/intel/iaa/iaa_crypto_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/crypto/intel/iaa/iaa_crypto_main.c b/drivers/crypto/intel/iaa/iaa_crypto_main.c +index 23f585219fb4b..d0058757b0000 100644 +--- a/drivers/crypto/intel/iaa/iaa_crypto_main.c ++++ b/drivers/crypto/intel/iaa/iaa_crypto_main.c +@@ -805,7 +805,7 @@ static int save_iaa_wq(struct idxd_wq *wq) + if (!cpus_per_iaa) + cpus_per_iaa = 1; + out: +- return 0; ++ return ret; + } + + static void remove_iaa_wq(struct idxd_wq *wq) +-- +2.51.0 + diff --git a/queue-6.18/crypto-starfive-correctly-handle-return-of-sg_nents_.patch b/queue-6.18/crypto-starfive-correctly-handle-return-of-sg_nents_.patch new file mode 100644 index 0000000000..ea41778866 --- /dev/null +++ b/queue-6.18/crypto-starfive-correctly-handle-return-of-sg_nents_.patch @@ -0,0 +1,51 @@ +From 6b14d3923f07f822df7979a63e0be1a24be1afa2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:54:38 +0800 +Subject: crypto: starfive - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit e9eb52037a529fbb307c290e9951a62dd728b03d ] + +The return value of sg_nents_for_len was assigned to an unsigned long +in starfive_hash_digest, causing negative error codes to be converted +to large positive integers. + +Add error checking for sg_nents_for_len and return immediately on +failure to prevent potential buffer overflows. + +Fixes: 7883d1b28a2b ("crypto: starfive - Add hash and HMAC support") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-hash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c +index e6839c7bfb73a..54b7af4a7aee8 100644 +--- a/drivers/crypto/starfive/jh7110-hash.c ++++ b/drivers/crypto/starfive/jh7110-hash.c +@@ -325,6 +325,7 @@ static int starfive_hash_digest(struct ahash_request *req) + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_dev *cryp = ctx->cryp; ++ int sg_len; + + memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); + +@@ -333,7 +334,10 @@ static int starfive_hash_digest(struct ahash_request *req) + rctx->in_sg = req->src; + rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + rctx->digsize = crypto_ahash_digestsize(tfm); +- rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ if (sg_len < 0) ++ return sg_len; ++ rctx->in_sg_len = sg_len; + ctx->rctx = rctx; + + return crypto_transfer_hash_request_to_engine(cryp->engine, req); +-- +2.51.0 + diff --git a/queue-6.18/docs-kdoc-fix-duplicate-section-warning-message.patch b/queue-6.18/docs-kdoc-fix-duplicate-section-warning-message.patch new file mode 100644 index 0000000000..2f6b9e2cc2 --- /dev/null +++ b/queue-6.18/docs-kdoc-fix-duplicate-section-warning-message.patch @@ -0,0 +1,107 @@ +From 78e6504b5df493156baaf742ec56ef06c506a1e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 12:58:32 -0700 +Subject: docs: kdoc: fix duplicate section warning message + +From: Jacob Keller + +[ Upstream commit e5e7ca66a7fc6b8073c30a048e1157b88d427980 ] + +The python version of the kernel-doc parser emits some strange warnings +with just a line number in certain cases: + +$ ./scripts/kernel-doc -Wall -none 'include/linux/virtio_config.h' +Warning: 174 +Warning: 184 +Warning: 190 +Warning: include/linux/virtio_config.h:226 No description found for return value of '__virtio_test_bit' +Warning: include/linux/virtio_config.h:259 No description found for return value of 'virtio_has_feature' +Warning: include/linux/virtio_config.h:283 No description found for return value of 'virtio_has_dma_quirk' +Warning: include/linux/virtio_config.h:392 No description found for return value of 'virtqueue_set_affinity' + +I eventually tracked this down to the lone call of emit_msg() in the +KernelEntry class, which looks like: + + self.emit_msg(self.new_start_line, f"duplicate section name '{name}'\n") + +This looks like all the other emit_msg calls. Unfortunately, the definition +within the KernelEntry class takes only a message parameter and not a line +number. The intended message is passed as the warning! + +Pass the filename to the KernelEntry class, and use this to build the log +message in the same way as the KernelDoc class does. + +To avoid future errors, mark the warning parameter for both emit_msg +definitions as a keyword-only argument. This will prevent accidentally +passing a string as the warning parameter in the future. + +Also fix the call in dump_section to avoid an unnecessary additional +newline. + +Fixes: e3b42e94cf10 ("scripts/lib/kdoc/kdoc_parser.py: move kernel entry to a class") +Signed-off-by: Jacob Keller +Signed-off-by: Jonathan Corbet +Message-ID: <20251030-jk-fix-kernel-doc-duplicate-return-warning-v2-1-ec4b5c662881@intel.com> +Signed-off-by: Sasha Levin +--- + scripts/lib/kdoc/kdoc_parser.py | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py +index 2376f180b1fa9..ccbc1fe4b7ccd 100644 +--- a/scripts/lib/kdoc/kdoc_parser.py ++++ b/scripts/lib/kdoc/kdoc_parser.py +@@ -274,6 +274,8 @@ class KernelEntry: + + self.leading_space = None + ++ self.fname = fname ++ + # State flags + self.brcount = 0 + self.declaration_start_line = ln + 1 +@@ -288,9 +290,11 @@ class KernelEntry: + return '\n'.join(self._contents) + '\n' + + # TODO: rename to emit_message after removal of kernel-doc.pl +- def emit_msg(self, log_msg, warning=True): ++ def emit_msg(self, ln, msg, *, warning=True): + """Emit a message""" + ++ log_msg = f"{self.fname}:{ln} {msg}" ++ + if not warning: + self.config.log.info(log_msg) + return +@@ -336,7 +340,7 @@ class KernelEntry: + # Only warn on user-specified duplicate section names + if name != SECTION_DEFAULT: + self.emit_msg(self.new_start_line, +- f"duplicate section name '{name}'\n") ++ f"duplicate section name '{name}'") + # Treat as a new paragraph - add a blank line + self.sections[name] += '\n' + contents + else: +@@ -387,15 +391,15 @@ class KernelDoc: + self.emit_msg(0, + 'Python 3.7 or later is required for correct results') + +- def emit_msg(self, ln, msg, warning=True): ++ def emit_msg(self, ln, msg, *, warning=True): + """Emit a message""" + +- log_msg = f"{self.fname}:{ln} {msg}" +- + if self.entry: +- self.entry.emit_msg(log_msg, warning) ++ self.entry.emit_msg(ln, msg, warning=warning) + return + ++ log_msg = f"{self.fname}:{ln} {msg}" ++ + if warning: + self.config.log.warning(log_msg) + else: +-- +2.51.0 + diff --git a/queue-6.18/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-6.18/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..a0412318a7 --- /dev/null +++ b/queue-6.18/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 4f5ec8ade33673cb4535eb8a99f25a20593af704 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 04eb647acc4e1..550a9f1d03f82 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1480,10 +1480,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-add-userq-object-va-track-helpers.patch b/queue-6.18/drm-amdgpu-add-userq-object-va-track-helpers.patch new file mode 100644 index 0000000000..017cfac914 --- /dev/null +++ b/queue-6.18/drm-amdgpu-add-userq-object-va-track-helpers.patch @@ -0,0 +1,207 @@ +From ef81f6b97ebda3118dfabb9785e5c1977eb76e8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 13:52:13 +0800 +Subject: drm/amdgpu: add userq object va track helpers + +From: Prike Liang + +[ Upstream commit 5cfa33fabf01f2cc0af6b1feed6e65cb81806a37 ] + +Add the userq object virtual address list_add() helpers +for tracking the userq obj va address usage. + +Signed-off-by: Prike Liang +Reviewed-by: Alex Deucher +Signed-off-by: Alex Deucher +Stable-dep-of: a0559012a18a ("drm/amdgpu/userq: fix SDMA and compute validation") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_object.h | 1 + + drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 44 ++++++++++++++++------ + drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h | 12 ++++-- + drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 16 ++++---- + 4 files changed, 52 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +index 656b8a931dae8..52c2d1731aabf 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +@@ -96,6 +96,7 @@ struct amdgpu_bo_va { + * if non-zero, cannot unmap from GPU because user queues may still access it + */ + unsigned int queue_refcount; ++ atomic_t userq_va_mapped; + }; + + struct amdgpu_bo { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +index 1add21160d218..79c7fa0a9ff7b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +@@ -44,10 +44,29 @@ u32 amdgpu_userq_get_supported_ip_mask(struct amdgpu_device *adev) + return userq_ip_mask; + } + +-int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, +- u64 expected_size) ++static int amdgpu_userq_buffer_va_list_add(struct amdgpu_usermode_queue *queue, ++ struct amdgpu_bo_va_mapping *va_map, u64 addr) ++{ ++ struct amdgpu_userq_va_cursor *va_cursor; ++ struct userq_va_list; ++ ++ va_cursor = kzalloc(sizeof(*va_cursor), GFP_KERNEL); ++ if (!va_cursor) ++ return -ENOMEM; ++ ++ INIT_LIST_HEAD(&va_cursor->list); ++ va_cursor->gpu_addr = addr; ++ atomic_set(&va_map->bo_va->userq_va_mapped, 1); ++ list_add(&va_cursor->list, &queue->userq_va_list); ++ ++ return 0; ++} ++ ++int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, ++ u64 addr, u64 expected_size) + { + struct amdgpu_bo_va_mapping *va_map; ++ struct amdgpu_vm *vm = queue->vm; + u64 user_addr; + u64 size; + int r = 0; +@@ -67,6 +86,7 @@ int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, + /* Only validate the userq whether resident in the VM mapping range */ + if (user_addr >= va_map->start && + va_map->last - user_addr + 1 >= size) { ++ amdgpu_userq_buffer_va_list_add(queue, va_map, user_addr); + amdgpu_bo_unreserve(vm->root.bo); + return 0; + } +@@ -185,6 +205,7 @@ amdgpu_userq_cleanup(struct amdgpu_userq_mgr *uq_mgr, + uq_funcs->mqd_destroy(uq_mgr, queue); + amdgpu_userq_fence_driver_free(queue); + idr_remove(&uq_mgr->userq_idr, queue_id); ++ list_del(&queue->userq_va_list); + kfree(queue); + } + +@@ -505,14 +526,7 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + goto unlock; + } + +- /* Validate the userq virtual address.*/ +- if (amdgpu_userq_input_va_validate(&fpriv->vm, args->in.queue_va, args->in.queue_size) || +- amdgpu_userq_input_va_validate(&fpriv->vm, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || +- amdgpu_userq_input_va_validate(&fpriv->vm, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { +- r = -EINVAL; +- kfree(queue); +- goto unlock; +- } ++ INIT_LIST_HEAD(&queue->userq_va_list); + queue->doorbell_handle = args->in.doorbell_handle; + queue->queue_type = args->in.ip_type; + queue->vm = &fpriv->vm; +@@ -523,6 +537,15 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + db_info.db_obj = &queue->db_obj; + db_info.doorbell_offset = args->in.doorbell_offset; + ++ /* Validate the userq virtual address.*/ ++ if (amdgpu_userq_input_va_validate(queue, args->in.queue_va, args->in.queue_size) || ++ amdgpu_userq_input_va_validate(queue, args->in.rptr_va, AMDGPU_GPU_PAGE_SIZE) || ++ amdgpu_userq_input_va_validate(queue, args->in.wptr_va, AMDGPU_GPU_PAGE_SIZE)) { ++ r = -EINVAL; ++ kfree(queue); ++ goto unlock; ++ } ++ + /* Convert relative doorbell offset into absolute doorbell index */ + index = amdgpu_userq_get_doorbell_index(uq_mgr, &db_info, filp); + if (index == (uint64_t)-EINVAL) { +@@ -548,7 +571,6 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args) + goto unlock; + } + +- + qid = idr_alloc(&uq_mgr->userq_idr, queue, 1, AMDGPU_MAX_USERQ_COUNT, GFP_KERNEL); + if (qid < 0) { + drm_file_err(uq_mgr->file, "Failed to allocate a queue id\n"); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +index c027dd9166727..dbc13a807ca82 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_userq.h +@@ -47,6 +47,11 @@ struct amdgpu_userq_obj { + struct amdgpu_bo *obj; + }; + ++struct amdgpu_userq_va_cursor { ++ u64 gpu_addr; ++ struct list_head list; ++}; ++ + struct amdgpu_usermode_queue { + int queue_type; + enum amdgpu_userq_state state; +@@ -66,6 +71,8 @@ struct amdgpu_usermode_queue { + u32 xcp_id; + int priority; + struct dentry *debugfs_queue; ++ ++ struct list_head userq_va_list; + }; + + struct amdgpu_userq_funcs { +@@ -136,7 +143,6 @@ int amdgpu_userq_stop_sched_for_enforce_isolation(struct amdgpu_device *adev, + u32 idx); + int amdgpu_userq_start_sched_for_enforce_isolation(struct amdgpu_device *adev, + u32 idx); +- +-int amdgpu_userq_input_va_validate(struct amdgpu_vm *vm, u64 addr, +- u64 expected_size); ++int amdgpu_userq_input_va_validate(struct amdgpu_usermode_queue *queue, ++ u64 addr, u64 expected_size); + #endif +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +index 1cd9eaeef38f9..5c63480dda9c4 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +@@ -298,8 +298,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + goto free_mqd; + } + +- if (amdgpu_userq_input_va_validate(queue->vm, compute_mqd->eop_va, +- max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE))) ++ r = amdgpu_userq_input_va_validate(queue, compute_mqd->eop_va, ++ max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE)); ++ if (r) + goto free_mqd; + + userq_props->eop_gpu_addr = compute_mqd->eop_va; +@@ -330,8 +331,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + userq_props->tmz_queue = + mqd_user->flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_SECURE; + +- if (amdgpu_userq_input_va_validate(queue->vm, mqd_gfx_v11->shadow_va, +- shadow_info.shadow_size)) ++ r = amdgpu_userq_input_va_validate(queue, mqd_gfx_v11->shadow_va, ++ shadow_info.shadow_size); ++ if (r) + goto free_mqd; + + kfree(mqd_gfx_v11); +@@ -350,9 +352,9 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + r = -ENOMEM; + goto free_mqd; + } +- +- if (amdgpu_userq_input_va_validate(queue->vm, mqd_sdma_v11->csa_va, +- shadow_info.csa_size)) ++ r = amdgpu_userq_input_va_validate(queue, mqd_sdma_v11->csa_va, ++ shadow_info.csa_size); ++ if (r) + goto free_mqd; + + userq_props->csa_addr = mqd_sdma_v11->csa_va; +-- +2.51.0 + diff --git a/queue-6.18/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch b/queue-6.18/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch new file mode 100644 index 0000000000..69ce671fb2 --- /dev/null +++ b/queue-6.18/drm-amdgpu-userq-fix-sdma-and-compute-validation.patch @@ -0,0 +1,91 @@ +From ccc05af6fe0aa4ce6732972a5fff4b68fab96763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 15:21:02 -0400 +Subject: drm/amdgpu/userq: fix SDMA and compute validation + +From: Alex Deucher + +[ Upstream commit a0559012a18a5a6ad87516e982892765a403b8ab ] + +The CSA and EOP buffers have different alignement requirements. +Hardcode them for now as a bug fix. A proper query will be added in +a subsequent patch. + +v2: verify gfx shadow helper callback (Prike) + +Fixes: 9e46b8bb0539 ("drm/amdgpu: validate userq buffer virtual address and size") +Reviewed-by: Prike Liang +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdgpu/mes_userqueue.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +index 5c63480dda9c4..f5aa83ff57f35 100644 +--- a/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c ++++ b/drivers/gpu/drm/amd/amdgpu/mes_userqueue.c +@@ -254,7 +254,6 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + struct amdgpu_mqd *mqd_hw_default = &adev->mqds[queue->queue_type]; + struct drm_amdgpu_userq_in *mqd_user = args_in; + struct amdgpu_mqd_prop *userq_props; +- struct amdgpu_gfx_shadow_info shadow_info; + int r; + + /* Structure to initialize MQD for userqueue using generic MQD init function */ +@@ -280,8 +279,6 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + userq_props->doorbell_index = queue->doorbell_index; + userq_props->fence_address = queue->fence_drv->gpu_addr; + +- if (adev->gfx.funcs->get_gfx_shadow_info) +- adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow_info, true); + if (queue->queue_type == AMDGPU_HW_IP_COMPUTE) { + struct drm_amdgpu_userq_mqd_compute_gfx11 *compute_mqd; + +@@ -299,7 +296,7 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + } + + r = amdgpu_userq_input_va_validate(queue, compute_mqd->eop_va, +- max_t(u32, PAGE_SIZE, AMDGPU_GPU_PAGE_SIZE)); ++ 2048); + if (r) + goto free_mqd; + +@@ -312,6 +309,14 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + kfree(compute_mqd); + } else if (queue->queue_type == AMDGPU_HW_IP_GFX) { + struct drm_amdgpu_userq_mqd_gfx11 *mqd_gfx_v11; ++ struct amdgpu_gfx_shadow_info shadow_info; ++ ++ if (adev->gfx.funcs->get_gfx_shadow_info) { ++ adev->gfx.funcs->get_gfx_shadow_info(adev, &shadow_info, true); ++ } else { ++ r = -EINVAL; ++ goto free_mqd; ++ } + + if (mqd_user->mqd_size != sizeof(*mqd_gfx_v11) || !mqd_user->mqd) { + DRM_ERROR("Invalid GFX MQD\n"); +@@ -335,6 +340,10 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + shadow_info.shadow_size); + if (r) + goto free_mqd; ++ r = amdgpu_userq_input_va_validate(queue, mqd_gfx_v11->csa_va, ++ shadow_info.csa_size); ++ if (r) ++ goto free_mqd; + + kfree(mqd_gfx_v11); + } else if (queue->queue_type == AMDGPU_HW_IP_DMA) { +@@ -353,7 +362,7 @@ static int mes_userq_mqd_create(struct amdgpu_userq_mgr *uq_mgr, + goto free_mqd; + } + r = amdgpu_userq_input_va_validate(queue, mqd_sdma_v11->csa_va, +- shadow_info.csa_size); ++ 32); + if (r) + goto free_mqd; + +-- +2.51.0 + diff --git a/queue-6.18/drm-amdkfd-assign-aid-to-uuid-in-topology-for-spx-mo.patch b/queue-6.18/drm-amdkfd-assign-aid-to-uuid-in-topology-for-spx-mo.patch new file mode 100644 index 0000000000..e0020663e0 --- /dev/null +++ b/queue-6.18/drm-amdkfd-assign-aid-to-uuid-in-topology-for-spx-mo.patch @@ -0,0 +1,40 @@ +From 79067850b156c31364e186d75f7c9ceae81da7bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 15:07:10 -0500 +Subject: drm/amdkfd: assign AID to uuid in topology for SPX mode + +From: Eric Huang + +[ Upstream commit 089702632f1dd38fadc9af13816485d6aa518dbb ] + +XCD id is assigned to uuid, which causes some performance +drop in SPX mode, assigning AID back will resolve the +issue. + +Fixes: 3a75edf93aae ("drm/amdkfd: set uuid for each partition in topology") +Signed-off-by: Eric Huang +Reviewed-by: Harish Kasiviswanathan +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +index 5c98746eb72df..811636af14eaa 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +@@ -530,7 +530,9 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr, + sysfs_show_32bit_prop(buffer, offs, "sdma_fw_version", + dev->gpu->kfd->sdma_fw_version); + sysfs_show_64bit_prop(buffer, offs, "unique_id", +- dev->gpu->xcp ? ++ dev->gpu->xcp && ++ (dev->gpu->xcp->xcp_mgr->mode != ++ AMDGPU_SPX_PARTITION_MODE) ? + dev->gpu->xcp->unique_id : + dev->gpu->adev->unique_id); + sysfs_show_32bit_prop(buffer, offs, "num_xcc", +-- +2.51.0 + diff --git a/queue-6.18/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch b/queue-6.18/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch new file mode 100644 index 0000000000..de65511f26 --- /dev/null +++ b/queue-6.18/drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch @@ -0,0 +1,91 @@ +From a253da4ed4b251f403232549ebac464d86c7398a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 14 Oct 2024 15:19:42 +0530 +Subject: drm: atmel-hlcdc: fix atmel_xlcdc_plane_setup_scaler() + +From: Cyrille Pitchen + +[ Upstream commit a312acdcec57b3955fbf1f3057c13a6d38e4aa2a ] + +On SoCs, like the SAM9X75, which embed the XLCDC ip, the registers that +configure the unified scaling engine were not filled with proper values. + +Indeed, for YCbCr formats, the VXSCFACT bitfield of the HEOCFG25 +register and the HXSCFACT bitfield of the HEOCFG27 register were +incorrect. + +For 4:2:0 formats, both vertical and horizontal factors for +chroma chanels should be divided by 2 from the factors for the luma +channel. Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VSXCFACT = VFACTOR / 2 +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +However, for 4:2:2 formats, only the horizontal factor for chroma +chanels should be divided by 2 from the factor for the luma channel; +the vertical factor is the same for all the luma and chroma channels. +Hence: + +HEOCFG24.VXSYFACT = VFACTOR +HEOCFG25.VXSCFACT = VFACTOR +HEOCFG26.HXSYFACT = HFACTOR +HEOCFG27.HXSCFACT = HFACTOR / 2 + +Fixes: d498771b0b83 ("drm: atmel_hlcdc: Add support for XLCDC using IP specific driver ops") +Signed-off-by: Cyrille Pitchen +Reviewed-by: Dmitry Baryshkov +Acked-by: Nicolas Ferre +Link: https://lore.kernel.org/r/20241014094942.325211-1-manikandan.m@microchip.com +Signed-off-by: Manikandan Muralidharan +Signed-off-by: Sasha Levin +--- + .../gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c | 27 ++++++++++++++++--- + 1 file changed, 24 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +index 4a7ba0918eca1..3787db014501e 100644 +--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c ++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +@@ -365,13 +365,34 @@ void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, + xfactor); + + /* +- * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration +- * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half ++ * With YCbCr 4:2:0 window resampling, configuration register ++ * LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT values are half + * the value of yfactor and xfactor. ++ * ++ * On the other hand, with YCbCr 4:2:2 window resampling, only the ++ * configuration register LCDC_HEOCFG27.HXSCFACT value is half the value ++ * of the xfactor; the value of LCDC_HEOCFG25.VXSCFACT is yfactor (no ++ * division by 2). + */ +- if (state->base.fb->format->format == DRM_FORMAT_YUV420) { ++ switch (state->base.fb->format->format) { ++ /* YCbCr 4:2:2 */ ++ case DRM_FORMAT_YUYV: ++ case DRM_FORMAT_UYVY: ++ case DRM_FORMAT_YVYU: ++ case DRM_FORMAT_VYUY: ++ case DRM_FORMAT_YUV422: ++ case DRM_FORMAT_NV61: ++ xfactor /= 2; ++ break; ++ ++ /* YCbCr 4:2:0 */ ++ case DRM_FORMAT_YUV420: ++ case DRM_FORMAT_NV21: + yfactor /= 2; + xfactor /= 2; ++ break; ++ default: ++ break; + } + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2, +-- +2.51.0 + diff --git a/queue-6.18/drm-imagination-fix-reference-to-devm_platform_get_a.patch b/queue-6.18/drm-imagination-fix-reference-to-devm_platform_get_a.patch new file mode 100644 index 0000000000..3f6b1fdc01 --- /dev/null +++ b/queue-6.18/drm-imagination-fix-reference-to-devm_platform_get_a.patch @@ -0,0 +1,40 @@ +From 5795ec09078de5c3147b825b050775e8fa89a676 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 16:00:28 +0100 +Subject: drm/imagination: Fix reference to + devm_platform_get_and_ioremap_resource() + +From: Geert Uytterhoeven + +[ Upstream commit f1aa93005d0d6fb3293ca9c3eb08d1d1557117bf ] + +The call to devm_platform_ioremap_resource() was replaced by a call to +devm_platform_get_and_ioremap_resource(), but the comment referring to +the function's possible returned error codes was not updated. + +Fixes: 927f3e0253c11276 ("drm/imagination: Implement MIPS firmware processor and MMU support") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: Matt Coster +Link: https://patch.msgid.link/2266514318480d17f52c7e5e67578dae6827914e.1761745586.git.geert+renesas@glider.be +Signed-off-by: Matt Coster +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/imagination/pvr_device.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c +index 294b6019b4155..78d6b8a0a4506 100644 +--- a/drivers/gpu/drm/imagination/pvr_device.c ++++ b/drivers/gpu/drm/imagination/pvr_device.c +@@ -48,7 +48,7 @@ + * + * Return: + * * 0 on success, or +- * * Any error returned by devm_platform_ioremap_resource(). ++ * * Any error returned by devm_platform_get_and_ioremap_resource(). + */ + static int + pvr_device_reg_init(struct pvr_device *pvr_dev) +-- +2.51.0 + diff --git a/queue-6.18/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-6.18/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..4d9e6f1e4e --- /dev/null +++ b/queue-6.18/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From e446182321395ce0e1b78e6218c9e5abdba025cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 10d60d2c2a568..6d7bf4afa78d3 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch b/queue-6.18/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch new file mode 100644 index 0000000000..451a029f6d --- /dev/null +++ b/queue-6.18/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch @@ -0,0 +1,42 @@ +From e6ca21bd23b359c04a5fa180d89e4e6197de3db7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:40:50 +0200 +Subject: drm/msm/a2xx: stop over-complaining about the legacy firmware + +From: Dmitry Baryshkov + +[ Upstream commit a3a22373fce576560757f5616eb48dbf85891d9c ] + +If the rootfs have a legacy A200 firmware, currently the driver will +complain each time the hw is reinited (which can happen a lot). E.g. +with GL testsuite the hw is reinited after each test, spamming the +console. + +Make sure that the message is printed only once: when we detect the +firmware that doesn't support protection. + +Fixes: 302295070d3c ("drm/msm/a2xx: support loading legacy (iMX) firmware") +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/688098/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +index ec38db45d8a36..963c0f669ee50 100644 +--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +@@ -234,7 +234,7 @@ static int a2xx_hw_init(struct msm_gpu *gpu) + * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225). + * Older firmware files, which lack protection support, have 0 instead. + */ +- if (ptr[1] == 0) { ++ if (ptr[1] == 0 && !a2xx_gpu->protection_disabled) { + dev_warn(gpu->dev->dev, + "Legacy firmware detected, disabling protection support\n"); + a2xx_gpu->protection_disabled = true; +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-a6xx-fix-the-gemnoc-workaround.patch b/queue-6.18/drm-msm-a6xx-fix-the-gemnoc-workaround.patch new file mode 100644 index 0000000000..9356652664 --- /dev/null +++ b/queue-6.18/drm-msm-a6xx-fix-the-gemnoc-workaround.patch @@ -0,0 +1,55 @@ +From 4fd1c492a87604bd54a8209d21cbb62b42ff996f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:30 +0530 +Subject: drm/msm/a6xx: Fix the gemnoc workaround + +From: Akhil P Oommen + +[ Upstream commit ff7a6de043fce21ea5891311746b16121b385c59 ] + +Correct the register offset and enable this workaround for all A7x +and newer GPUs to match the recommendation. Also, downstream does this +w/a after moving the fence to allow mode. So do the same. + +Fixes: dbfbb376b50c ("drm/msm/a6xx: Add A621 support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688997/ +Message-ID: <20251118-kaana-gpu-support-v4-3-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index 4e6dc16e4a4c4..605bb55de8d52 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -485,8 +485,9 @@ static void a6xx_gemnoc_workaround(struct a6xx_gmu *gmu) + * in the power down sequence not being fully executed. That in turn can + * prevent CX_GDSC from collapsing. Assert Qactive to avoid this. + */ +- if (adreno_is_a621(adreno_gpu) || adreno_is_7c3(adreno_gpu)) +- gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, BIT(0)); ++ if (adreno_is_a7xx(adreno_gpu) || (adreno_is_a621(adreno_gpu) || ++ adreno_is_7c3(adreno_gpu))) ++ gmu_write(gmu, REG_A6XX_GPU_GMU_CX_GMU_CX_FALNEXT_INTF, BIT(0)); + } + + /* Let the GMU know that we are about to go into slumber */ +@@ -522,10 +523,9 @@ static int a6xx_gmu_notify_slumber(struct a6xx_gmu *gmu) + } + + out: +- a6xx_gemnoc_workaround(gmu); +- + /* Put fence into allow mode */ + gmu_write(gmu, REG_A6XX_GMU_AO_AHB_FENCE_CTRL, 0); ++ a6xx_gemnoc_workaround(gmu); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch b/queue-6.18/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch new file mode 100644 index 0000000000..352f9d04d0 --- /dev/null +++ b/queue-6.18/drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch @@ -0,0 +1,56 @@ +From 32106ca91e4cd6a0d3d6598af5102523341fbfe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:29 +0530 +Subject: drm/msm/a6xx: Flush LRZ cache before PT switch + +From: Akhil P Oommen + +[ Upstream commit 180349b8407f3b268b2ceac0e590b8199e043081 ] + +As per the recommendation, A7x and newer GPUs should flush the LRZ cache +before switching the pagetable. Update a6xx_set_pagetable() to do this. +While we are at it, sync both BV and BR before issuing a +CP_RESET_CONTEXT_STATE command, to match the downstream sequence. + +Fixes: af66706accdf ("drm/msm/a6xx: Add skeleton A7xx support") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/688995/ +Message-ID: <20251118-kaana-gpu-support-v4-2-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +index b8f8ae940b55f..6f7ed07670b12 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +@@ -224,7 +224,7 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + OUT_RING(ring, submit->seqno - 1); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BOTH); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); + + /* Reset state used to synchronize BR and BV */ + OUT_PKT7(ring, CP_RESET_CONTEXT_STATE, 1); +@@ -235,7 +235,13 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, + CP_RESET_CONTEXT_STATE_0_RESET_GLOBAL_LOCAL_TS); + + OUT_PKT7(ring, CP_THREAD_CONTROL, 1); +- OUT_RING(ring, CP_SET_THREAD_BR); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BOTH); ++ ++ OUT_PKT7(ring, CP_EVENT_WRITE, 1); ++ OUT_RING(ring, LRZ_FLUSH); ++ ++ OUT_PKT7(ring, CP_THREAD_CONTROL, 1); ++ OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); + } + + if (!sysprof) { +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch b/queue-6.18/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch new file mode 100644 index 0000000000..e4d7575356 --- /dev/null +++ b/queue-6.18/drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch @@ -0,0 +1,92 @@ +From 33a3c480b699b5523ae89bbdc278bc805fd54f34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 14:20:39 +0530 +Subject: drm/msm/a6xx: Improve MX rail fallback in RPMH vote init + +From: Akhil P Oommen + +[ Upstream commit ca04ce7a2f22652fdf6489fa7e02e7d2c08698f4 ] + +Current logic assumes that the voltage corners in both MxG and MxA are +always same. This is not true for recent targets. So, rework the rpmh init +sequence to probe and calculate the votes with the respective rails, ie, +GX rails should use MxG as secondary rail and Cx rail should use MxA as +the secondary rail. + +Fixes: d6225e0cd096 ("drm/msm/adreno: Add support for X185 GPU") +Reviewed-by: Konrad Dybcio +Signed-off-by: Akhil P Oommen +Patchwork: https://patchwork.freedesktop.org/patch/689014/ +Message-ID: <20251118-kaana-gpu-support-v4-12-86eeb8e93fb6@oss.qualcomm.com> +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +index 605bb55de8d52..21a3f9b0ab4c2 100644 +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -1492,13 +1492,14 @@ static unsigned int a6xx_gmu_get_arc_level(struct device *dev, + } + + static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, +- unsigned long *freqs, int freqs_count, const char *id) ++ unsigned long *freqs, int freqs_count, ++ const char *pri_id, const char *sec_id) + { + int i, j; + const u16 *pri, *sec; + size_t pri_count, sec_count; + +- pri = cmd_db_read_aux_data(id, &pri_count); ++ pri = cmd_db_read_aux_data(pri_id, &pri_count); + if (IS_ERR(pri)) + return PTR_ERR(pri); + /* +@@ -1509,13 +1510,7 @@ static int a6xx_gmu_rpmh_arc_votes_init(struct device *dev, u32 *votes, + if (!pri_count) + return -EINVAL; + +- /* +- * Some targets have a separate gfx mxc rail. So try to read that first and then fall back +- * to regular mx rail if it is missing +- */ +- sec = cmd_db_read_aux_data("gmxc.lvl", &sec_count); +- if (IS_ERR(sec) && sec != ERR_PTR(-EPROBE_DEFER)) +- sec = cmd_db_read_aux_data("mx.lvl", &sec_count); ++ sec = cmd_db_read_aux_data(sec_id, &sec_count); + if (IS_ERR(sec)) + return PTR_ERR(sec); + +@@ -1583,15 +1578,24 @@ static int a6xx_gmu_rpmh_votes_init(struct a6xx_gmu *gmu) + struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; + const struct a6xx_info *info = adreno_gpu->info->a6xx; + struct msm_gpu *gpu = &adreno_gpu->base; ++ const char *sec_id; ++ const u16 *gmxc; + int ret; + ++ gmxc = cmd_db_read_aux_data("gmxc.lvl", NULL); ++ if (gmxc == ERR_PTR(-EPROBE_DEFER)) ++ return -EPROBE_DEFER; ++ ++ /* If GMxC is present, prefer that as secondary rail for GX votes */ ++ sec_id = IS_ERR_OR_NULL(gmxc) ? "mx.lvl" : "gmxc.lvl"; ++ + /* Build the GX votes */ + ret = a6xx_gmu_rpmh_arc_votes_init(&gpu->pdev->dev, gmu->gx_arc_votes, +- gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl"); ++ gmu->gpu_freqs, gmu->nr_gpu_freqs, "gfx.lvl", sec_id); + + /* Build the CX votes */ + ret |= a6xx_gmu_rpmh_arc_votes_init(gmu->dev, gmu->cx_arc_votes, +- gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl"); ++ gmu->gmu_freqs, gmu->nr_gmu_freqs, "cx.lvl", "mx.lvl"); + + /* Build the interconnect votes */ + if (info->bcms && gmu->nr_gpu_bws > 1) +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch b/queue-6.18/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch new file mode 100644 index 0000000000..5904dba781 --- /dev/null +++ b/queue-6.18/drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch @@ -0,0 +1,45 @@ +From c1551b8c7699f82927d4dc3a93be1aaca72a7b78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:35:17 +0200 +Subject: drm/msm/dpu: drop dpu_hw_dsc_destroy() prototype + +From: Dmitry Baryshkov + +[ Upstream commit d9792823d18ff9895eaf5769a29a54804f24bc25 ] + +The commit a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for +HW blocks") dropped all dpu_hw_foo_destroy() functions, but the +prototype for dpu_hw_dsc_destroy() was omitted. Drop it now to clean up +the header. + +Fixes: a106ed98af68 ("drm/msm/dpu: use devres-managed allocation for HW blocks") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Reviewed-by: Jessica Zhang +Patchwork: https://patchwork.freedesktop.org/patch/683697/ +Link: https://lore.kernel.org/r/20251027-dpu-drop-dsc-destroy-v1-1-968128de4bf6@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +index b7013c9822d23..cc7cc6f6f7cda 100644 +--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h ++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +@@ -71,12 +71,6 @@ struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(struct drm_device *dev, + const struct dpu_dsc_cfg *cfg, + void __iomem *addr); + +-/** +- * dpu_hw_dsc_destroy - destroys dsc driver context +- * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init +- */ +-void dpu_hw_dsc_destroy(struct dpu_hw_dsc *dsc); +- + static inline struct dpu_hw_dsc *to_dpu_hw_dsc(struct dpu_hw_blk *hw) + { + return container_of(hw, struct dpu_hw_dsc, base); +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch b/queue-6.18/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch new file mode 100644 index 0000000000..ed39c48b63 --- /dev/null +++ b/queue-6.18/drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch @@ -0,0 +1,60 @@ +From 5b4c8e02dace6f0fc4a40e525c522185011c6a6b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 01:19:47 +0800 +Subject: drm/msm: fix missing NULL check after kcalloc in crashstate_get_bos() + +From: Huiwen He + +[ Upstream commit 3065e6a4d3594b42dae6176b3e2c0c3563cf94b8 ] + +The crashstate_get_bos() function allocates memory for `state->bos` +using kcalloc(), but the vmbind path does not check for allocation +failure before dereferencing it in the following drm_gpuvm_for_each_va() +loop. This could lead to a NULL pointer dereference if memory allocation +fails. + +Fix this by wrapping the drm_gpuvm_for_each_va() loop with a NULL check +on state->bos, similar to the safety check in the non-vmbind path. + +Fixes: af9aa6f316b3d ("drm/msm: Crashdump support for sparse") +Signed-off-by: Huiwen He +Patchwork: https://patchwork.freedesktop.org/patch/687556/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gpu.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c +index e23f70fbc8cb2..dd0605fe1243d 100644 +--- a/drivers/gpu/drm/msm/msm_gpu.c ++++ b/drivers/gpu/drm/msm/msm_gpu.c +@@ -287,16 +287,17 @@ static void crashstate_get_bos(struct msm_gpu_state *state, struct msm_gem_submi + + state->bos = kcalloc(cnt, sizeof(struct msm_gpu_state_bo), GFP_KERNEL); + +- drm_gpuvm_for_each_va (vma, submit->vm) { +- bool dump = rd_full || (vma->flags & MSM_VMA_DUMP); ++ if (state->bos) ++ drm_gpuvm_for_each_va(vma, submit->vm) { ++ bool dump = rd_full || (vma->flags & MSM_VMA_DUMP); + +- /* Skip MAP_NULL/PRR VMAs: */ +- if (!vma->gem.obj) +- continue; ++ /* Skip MAP_NULL/PRR VMAs: */ ++ if (!vma->gem.obj) ++ continue; + +- msm_gpu_crashstate_get_bo(state, vma->gem.obj, vma->va.addr, +- dump, vma->gem.offset, vma->va.range); +- } ++ msm_gpu_crashstate_get_bo(state, vma->gem.obj, vma->va.addr, ++ dump, vma->gem.offset, vma->va.range); ++ } + + drm_exec_fini(&exec); + } else { +-- +2.51.0 + diff --git a/queue-6.18/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch b/queue-6.18/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch new file mode 100644 index 0000000000..4db1ce8ed4 --- /dev/null +++ b/queue-6.18/drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch @@ -0,0 +1,44 @@ +From 92289ba9a6f62b3a661eb5e5d606e255963bd933 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 01:04:11 +0800 +Subject: drm/msm: Fix NULL pointer dereference in crashstate_get_vm_logs() + +From: Huiwen He + +[ Upstream commit 3099e0247e3217e1b39c1c61766e06ec3d13835f ] + +crashstate_get_vm_logs() did not check the return value of +kmalloc_array(). In low-memory situations, kmalloc_array() may return +NULL, leading to a NULL pointer dereference when the function later +accesses state->vm_logs. + +Fix this by checking the return value of kmalloc_array() and setting +state->nr_vm_logs to 0 if allocation fails. + +Fixes: 9edc52967cc7 ("drm/msm: Add VM logging for VM_BIND updates") +Signed-off-by: Huiwen He +Patchwork: https://patchwork.freedesktop.org/patch/687555/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/msm_gpu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c +index 17759abc46d7d..e23f70fbc8cb2 100644 +--- a/drivers/gpu/drm/msm/msm_gpu.c ++++ b/drivers/gpu/drm/msm/msm_gpu.c +@@ -348,6 +348,10 @@ static void crashstate_get_vm_logs(struct msm_gpu_state *state, struct msm_gem_v + + state->vm_logs = kmalloc_array( + state->nr_vm_logs, sizeof(vm->log[0]), GFP_KERNEL); ++ if (!state->vm_logs) { ++ state->nr_vm_logs = 0; ++ } ++ + for (int i = 0; i < state->nr_vm_logs; i++) { + int idx = (i + first) & vm_log_mask; + +-- +2.51.0 + diff --git a/queue-6.18/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch b/queue-6.18/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch new file mode 100644 index 0000000000..962d6acc88 --- /dev/null +++ b/queue-6.18/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch @@ -0,0 +1,55 @@ +From 632bda4bb81150b0d1a1f51ae4025ce4d45bba52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 17:03:22 -0600 +Subject: drm/nouveau: restrict the flush page to a 32-bit address + +From: Timur Tabi + +[ Upstream commit 04d98b3452331fa53ec3b698b66273af6ef73288 ] + +The flush page DMA address is stored in a special register that is not +associated with the GPU's standard DMA range. For example, on Turing, +the GPU's MMU can handle 47-bit addresses, but the flush page address +register is limited to 40 bits. + +At the point during device initialization when the flush page is +allocated, the DMA mask is still at its default of 32 bits. So even +though it's unlikely that the flush page could exist above a 40-bit +address, the dma_map_page() call could fail, e.g. if IOMMU is disabled +and the address is above 32 bits. The simplest way to achieve all +constraints is to allocate the page in the DMA32 zone. Since the flush +page is literally just a page, this is an acceptable limitation. The +alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper +and later) bits, but that could have unforseen side effects. + +In situations where the flush page is allocated above 32 bits and IOMMU +is disabled, you will get an error like this: + +nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0). + +Fixes: 5728d064190e ("drm/nouveau/fb: handle sysmem flush page from common code") +Signed-off-by: Timur Tabi +Reviewed-by: Lyude Paul +Signed-off-by: Lyude Paul +Link: https://patch.msgid.link/20251113230323.1271726-1-ttabi@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +index 8a286a9349ac6..7ce1b65e2c1c2 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +@@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, + mutex_init(&fb->tags.mutex); + + if (func->sysmem.flush_page_init) { +- fb->sysmem.flush_page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + if (!fb->sysmem.flush_page) + return -ENOMEM; + +-- +2.51.0 + diff --git a/queue-6.18/drm-nova-select-nova_core.patch b/queue-6.18/drm-nova-select-nova_core.patch new file mode 100644 index 0000000000..f7c19accbe --- /dev/null +++ b/queue-6.18/drm-nova-select-nova_core.patch @@ -0,0 +1,37 @@ +From a9fdac8600d1d282ee97d3381d6eb42829f2a6b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 12:00:53 +0100 +Subject: drm: nova: select NOVA_CORE + +From: Danilo Krummrich + +[ Upstream commit 97ad568cd6a58804129ba071f3258b5c4782fb0d ] + +The nova-drm driver does not provide any value without nova-core being +selected as well, hence select NOVA_CORE. + +Fixes: cdeaeb9dd762 ("drm: nova-drm: add initial driver skeleton") +Reviewed-by: Alexandre Courbot +Reviewed-by: John Hubbard +Link: https://patch.msgid.link/20251028110058.340320-2-dakr@kernel.org +Signed-off-by: Danilo Krummrich +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nova/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/nova/Kconfig b/drivers/gpu/drm/nova/Kconfig +index cca6a3fea879b..bd1df08791911 100644 +--- a/drivers/gpu/drm/nova/Kconfig ++++ b/drivers/gpu/drm/nova/Kconfig +@@ -4,6 +4,7 @@ config DRM_NOVA + depends on PCI + depends on RUST + select AUXILIARY_BUS ++ select NOVA_CORE + default n + help + Choose this if you want to build the Nova DRM driver for Nvidia +-- +2.51.0 + diff --git a/queue-6.18/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-6.18/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..576f400469 --- /dev/null +++ b/queue-6.18/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From a701cd118598c67b85463b80603d94d836bdbb55 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 5491d601681cf..66c30db3b73a7 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -192,7 +192,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + struct mipi_dsi_multi_context dsi_ctx = { .dsi = ctx->dsi }; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + mipi_dsi_dcs_set_display_off_multi(&dsi_ctx); + +-- +2.51.0 + diff --git a/queue-6.18/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch b/queue-6.18/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch new file mode 100644 index 0000000000..f02eb1e852 --- /dev/null +++ b/queue-6.18/drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch @@ -0,0 +1,42 @@ +From 0f32595d3fa0de690691e5e9a7c1241ab39e7134 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:56 +0200 +Subject: drm/panel: visionox-rm69299: Fix clock frequency for SHIFT6mq +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit d298062312724606855294503acebc7ee55ffbca ] + +Make the clock frequency match what the sdm845 downstream kernel +uses. Otherwise the panel stays black. + +Fixes: 783334f366b18 ("drm/panel: visionox-rm69299: support the variant found in the SHIFT6mq") +Signed-off-by: Guido Günther +Reviewed-by: Neil Armstrong +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-1-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 909c280eab1fb..5491d601681cf 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -247,7 +247,7 @@ static const struct drm_display_mode visionox_rm69299_1080x2248_60hz = { + }; + + static const struct drm_display_mode visionox_rm69299_1080x2160_60hz = { +- .clock = 158695, ++ .clock = (2160 + 8 + 4 + 4) * (1080 + 26 + 2 + 36) * 60 / 1000, + .hdisplay = 1080, + .hsync_start = 1080 + 26, + .hsync_end = 1080 + 26 + 2, +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch b/queue-6.18/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch new file mode 100644 index 0000000000..50f5e157c2 --- /dev/null +++ b/queue-6.18/drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch @@ -0,0 +1,64 @@ +From 3ba3c1b8fe98a9fb950584bcbe2d55c9bdc5a808 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 17:21:18 +0000 +Subject: drm/panthor: Avoid adding of kernel BOs to extobj list + +From: Akash Goel + +[ Upstream commit ce04ec03a9c2c4f3e60e26f21311b25d5a478208 ] + +The kernel BOs unnecessarily got added to the external objects list +of drm_gpuvm, when mapping to GPU, which would have resulted in few +extra CPU cycles being spent at the time of job submission as +drm_exec_until_all_locked() loop iterates over all external objects. + +Kernel BOs are private to a VM and so they share the dma_resv object of +the dummy GEM object created for a VM. Use of DRM_EXEC_IGNORE_DUPLICATES +flag ensured the recursive locking of the dummy GEM object was ignored. +Also no extra space got allocated to add fences to the dma_resv object +of dummy GEM object. So no other impact apart from few extra CPU cycles. + +This commit sets the pointer to dma_resv object of GEM object of +kernel BOs before they are mapped to GPU, to prevent them from +being added to external objects list. + +v2: Add R-bs and fixes tags + +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251120172118.2741724-1-akash.goel@arm.com +Signed-off-by: Boris Brezillon +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index 14ed09d700f2f..43471babff86c 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -144,6 +144,9 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + bo = to_panthor_bo(&obj->base); + kbo->obj = &obj->base; + bo->flags = bo_flags; ++ bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); ++ drm_gem_object_get(bo->exclusive_vm_root_gem); ++ bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + + if (vm == panthor_fw_vm(ptdev)) + debug_flags |= PANTHOR_DEBUGFS_GEM_USAGE_FLAG_FW_MAPPED; +@@ -167,9 +170,6 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, + goto err_free_va; + + kbo->vm = panthor_vm_get(vm); +- bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm); +- drm_gem_object_get(bo->exclusive_vm_root_gem); +- bo->base.base.resv = bo->exclusive_vm_root_gem->resv; + return kbo; + + err_free_va: +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-fix-group_free_queue-for-partially-initi.patch b/queue-6.18/drm-panthor-fix-group_free_queue-for-partially-initi.patch new file mode 100644 index 0000000000..2101d0b3d5 --- /dev/null +++ b/queue-6.18/drm-panthor-fix-group_free_queue-for-partially-initi.patch @@ -0,0 +1,45 @@ +From 29940046cc7370d6b685d038f52eb05e156300e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:18 +0100 +Subject: drm/panthor: Fix group_free_queue() for partially initialized queues +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Boris Brezillon + +[ Upstream commit 94a6d20feadbbe24e8a7b1c56394789ea5358fcc ] + +group_free_queue() can be called on a partially initialized queue +object if something fails in group_create_queue(). Make sure we don't +call drm_sched_entity_destroy() on an entity that hasn't been +initialized. + +Fixes: 7d9c3442b02a ("drm/panthor: Defer scheduler entitiy destruction to queue release") +Reviewed-by: Adrián Larumbe +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 85ef9a7acc147..a39f0fb370dc6 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -895,7 +895,8 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue * + if (IS_ERR_OR_NULL(queue)) + return; + +- drm_sched_entity_destroy(&queue->entity); ++ if (queue->entity.fence_context) ++ drm_sched_entity_destroy(&queue->entity); + + if (queue->scheduler.ops) + drm_sched_fini(&queue->scheduler); +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-fix-potential-memleak-of-vma-structure.patch b/queue-6.18/drm-panthor-fix-potential-memleak-of-vma-structure.patch new file mode 100644 index 0000000000..5618437481 --- /dev/null +++ b/queue-6.18/drm-panthor-fix-potential-memleak-of-vma-structure.patch @@ -0,0 +1,69 @@ +From ab7d4771cd942fe92c9b8baf107fe256a38dc673 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 09:10:42 +0100 +Subject: drm/panthor: Fix potential memleak of vma structure + +From: Akash Goel + +[ Upstream commit 4492d54d59872bb72e119ff9f77969ab4d8a0e6b ] + +This commit addresses a memleak issue of panthor_vma (or drm_gpuva) +structure in Panthor driver, that can happen if the GPU page table +update operation to map the pages fail. +The issue is very unlikely to occur in practice. + +v2: Add panthor_vm_op_ctx_return_vma() helper (Boris) + +v3: Add WARN_ON_ONCE (Boris) + +Fixes: 647810ec2476 ("drm/panthor: Add the MMU/VM logical block") +Signed-off-by: Akash Goel +Reviewed-by: Boris Brezillon +Reviewed-by: Steven Price +Signed-off-by: Steven Price +Link: https://patch.msgid.link/20251021081042.1377406-1-akash.goel@arm.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_mmu.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_mmu.c b/drivers/gpu/drm/panthor/panthor_mmu.c +index 7870e7dbaa5d4..15961629872e1 100644 +--- a/drivers/gpu/drm/panthor/panthor_mmu.c ++++ b/drivers/gpu/drm/panthor/panthor_mmu.c +@@ -1146,6 +1146,20 @@ static void panthor_vm_cleanup_op_ctx(struct panthor_vm_op_ctx *op_ctx, + } + } + ++static void ++panthor_vm_op_ctx_return_vma(struct panthor_vm_op_ctx *op_ctx, ++ struct panthor_vma *vma) ++{ ++ for (u32 i = 0; i < ARRAY_SIZE(op_ctx->preallocated_vmas); i++) { ++ if (!op_ctx->preallocated_vmas[i]) { ++ op_ctx->preallocated_vmas[i] = vma; ++ return; ++ } ++ } ++ ++ WARN_ON_ONCE(1); ++} ++ + static struct panthor_vma * + panthor_vm_op_ctx_get_vma(struct panthor_vm_op_ctx *op_ctx) + { +@@ -2085,8 +2099,10 @@ static int panthor_gpuva_sm_step_map(struct drm_gpuva_op *op, void *priv) + ret = panthor_vm_map_pages(vm, op->map.va.addr, flags_to_prot(vma->flags), + op_ctx->map.sgt, op->map.gem.offset, + op->map.va.range); +- if (ret) ++ if (ret) { ++ panthor_vm_op_ctx_return_vma(op_ctx, vma); + return ret; ++ } + + /* Ref owned by the mapping now, clear the obj field so we don't release the + * pinning/obj ref behind GPUVA's back. +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-fix-race-with-suspend-during-unplug.patch b/queue-6.18/drm-panthor-fix-race-with-suspend-during-unplug.patch new file mode 100644 index 0000000000..d7f5907604 --- /dev/null +++ b/queue-6.18/drm-panthor-fix-race-with-suspend-during-unplug.patch @@ -0,0 +1,58 @@ +From 843eca44565d7e173d632e0bbb7b87d87396267e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 12:32:41 +0200 +Subject: drm/panthor: Fix race with suspend during unplug + +From: Ketil Johnsen + +[ Upstream commit 08be57e6e8aa20ea5a6dd2552e38ac168d6a9b11 ] + +There is a race between panthor_device_unplug() and +panthor_device_suspend() which can lead to IRQ handlers running on a +powered down GPU. This is how it can happen: +- unplug routine calls drm_dev_unplug() +- panthor_device_suspend() can now execute, and will skip a lot of + important work because the device is currently marked as unplugged. +- IRQs will remain active in this case and IRQ handlers can therefore + try to access a powered down GPU. + +The fix is simply to take the PM ref in panthor_device_unplug() a +little bit earlier, before drm_dev_unplug(). + +Signed-off-by: Ketil Johnsen +Fixes: 5fe909cae118a ("drm/panthor: Add the device logical block") +Reviewed-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Reviewed-by: Steven Price +Link: https://patch.msgid.link/20251022103242.1083311-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c +index 81df49880bd87..962a10e00848e 100644 +--- a/drivers/gpu/drm/panthor/panthor_device.c ++++ b/drivers/gpu/drm/panthor/panthor_device.c +@@ -83,6 +83,8 @@ void panthor_device_unplug(struct panthor_device *ptdev) + return; + } + ++ drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); ++ + /* Call drm_dev_unplug() so any access to HW blocks happening after + * that point get rejected. + */ +@@ -93,8 +95,6 @@ void panthor_device_unplug(struct panthor_device *ptdev) + */ + mutex_unlock(&ptdev->unplug.lock); + +- drm_WARN_ON(&ptdev->base, pm_runtime_get_sync(ptdev->base.dev) < 0); +- + /* Now, try to cleanly shutdown the GPU before the device resources + * get reclaimed. + */ +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch b/queue-6.18/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch new file mode 100644 index 0000000000..094a22bffa --- /dev/null +++ b/queue-6.18/drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch @@ -0,0 +1,68 @@ +From 956c333277cd5eed5b0db09994e042342f62adc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:48:15 +0100 +Subject: drm/panthor: Fix UAF on kernel BO VA nodes + +From: Boris Brezillon + +[ Upstream commit 98dd5143447af0ee33551776d8b2560c35d0bc4a ] + +If the MMU is down, panthor_vm_unmap_range() might return an error. +We expect the page table to be updated still, and if the MMU is blocked, +the rest of the GPU should be blocked too, so no risk of accessing +physical memory returned to the system (which the current code doesn't +cover for anyway). + +Proceed with the rest of the cleanup instead of bailing out and leaving +the va_node inserted in the drm_mm, which leads to UAF when other +adjacent nodes are removed from the drm_mm tree. + +Reported-by: Lars-Ivar Hesselberg Simonsen +Closes: https://gitlab.freedesktop.org/panfrost/linux/-/issues/57 +Fixes: 8a1cc07578bf ("drm/panthor: Add GEM logical block") +Signed-off-by: Boris Brezillon +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251031154818.821054-2-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_gem.c | 14 +++----------- + 1 file changed, 3 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/panthor/panthor_gem.c b/drivers/gpu/drm/panthor/panthor_gem.c +index 3f43686f01958..14ed09d700f2f 100644 +--- a/drivers/gpu/drm/panthor/panthor_gem.c ++++ b/drivers/gpu/drm/panthor/panthor_gem.c +@@ -86,7 +86,6 @@ static void panthor_gem_free_object(struct drm_gem_object *obj) + void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + { + struct panthor_vm *vm; +- int ret; + + if (IS_ERR_OR_NULL(bo)) + return; +@@ -94,18 +93,11 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) + vm = bo->vm; + panthor_kernel_bo_vunmap(bo); + +- if (drm_WARN_ON(bo->obj->dev, +- to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) +- goto out_free_bo; +- +- ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); +- if (ret) +- goto out_free_bo; +- ++ drm_WARN_ON(bo->obj->dev, ++ to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm)); ++ panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); + panthor_vm_free_va(vm, &bo->va_node); + drm_gem_object_put(bo->obj); +- +-out_free_bo: + panthor_vm_put(vm); + kfree(bo); + } +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch b/queue-6.18/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch new file mode 100644 index 0000000000..266f22106c --- /dev/null +++ b/queue-6.18/drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch @@ -0,0 +1,43 @@ +From 9b9dab669636ecde5d1e5a13946543758d2afeb3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 15:02:15 +0100 +Subject: drm/panthor: Fix UAF race between device unplug and FW event + processing + +From: Ketil Johnsen + +[ Upstream commit 7051f6ba968fa69918d72cc26de4d6cf7ea05b90 ] + +The function panthor_fw_unplug() will free the FW memory sections. +The problem is that there could still be pending FW events which are yet +not handled at this point. process_fw_events_work() can in this case try +to access said freed memory. + +Simply call disable_work_sync() to both drain and prevent future +invocation of process_fw_events_work(). + +Signed-off-by: Ketil Johnsen +Fixes: de85488138247 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Link: https://patch.msgid.link/20251027140217.121274-1-ketil.johnsen@arm.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index a39f0fb370dc6..0279e19aadae9 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3859,6 +3859,7 @@ void panthor_sched_unplug(struct panthor_device *ptdev) + struct panthor_scheduler *sched = ptdev->scheduler; + + cancel_delayed_work_sync(&sched->tick_work); ++ disable_work_sync(&sched->fw_events_work); + + mutex_lock(&sched->lock); + if (sched->pm.has_ref) { +-- +2.51.0 + diff --git a/queue-6.18/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch b/queue-6.18/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch new file mode 100644 index 0000000000..554a3091f6 --- /dev/null +++ b/queue-6.18/drm-panthor-handle-errors-returned-by-drm_sched_enti.patch @@ -0,0 +1,39 @@ +From 3af9f3bfc13bb2c6cbe2849f3286345ab251123c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 17:03:17 +0100 +Subject: drm/panthor: Handle errors returned by drm_sched_entity_init() + +From: Boris Brezillon + +[ Upstream commit bb7939e332c64c4ef33974a0eae4f3841acfa8eb ] + +In practice it's not going to fail because we're passing the current +sanity checks done by drm_sched_entity_init(), and that's the only +reason it would return an error, but better safe than sorry. + +Fixes: de8548813824 ("drm/panthor: Add the scheduler logical block") +Reviewed-by: Liviu Dudau +Signed-off-by: Boris Brezillon +Link: https://patch.msgid.link/20251031160318.832427-1-boris.brezillon@collabora.com +Signed-off-by: Liviu Dudau +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panthor/panthor_sched.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpu/drm/panthor/panthor_sched.c b/drivers/gpu/drm/panthor/panthor_sched.c +index 3d1f57e3990f4..85ef9a7acc147 100644 +--- a/drivers/gpu/drm/panthor/panthor_sched.c ++++ b/drivers/gpu/drm/panthor/panthor_sched.c +@@ -3403,6 +3403,8 @@ group_create_queue(struct panthor_group *group, + + drm_sched = &queue->scheduler; + ret = drm_sched_entity_init(&queue->entity, 0, &drm_sched, 1, NULL); ++ if (ret) ++ goto err_free_queue; + + return queue; + +-- +2.51.0 + diff --git a/queue-6.18/drm-rcar-du-dsi-fix-missing-parameter-in-rxsetr_.en-.patch b/queue-6.18/drm-rcar-du-dsi-fix-missing-parameter-in-rxsetr_.en-.patch new file mode 100644 index 0000000000..b713193736 --- /dev/null +++ b/queue-6.18/drm-rcar-du-dsi-fix-missing-parameter-in-rxsetr_.en-.patch @@ -0,0 +1,43 @@ +From 9ac594b92768e61611bbd7b1852c89b2143ed4c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 00:28:11 +0100 +Subject: drm/rcar-du: dsi: Fix missing parameter in RXSETR_...EN macros + +From: Marek Vasut + +[ Upstream commit 42bbf82b73bda18bbc3e158cb6fda040bb586feb ] + +The RXSETR_CRCEN(n) and RXSETR_ECCEN(n) macros both take parameter (n), +add the missing macro parameter. Neither of those macros is used by the +driver, so for now the bug is harmless. + +Fixes: 685e8dae19df ("drm/rcar-du: dsi: Implement DSI command support") +Reviewed-by: Laurent Pinchart +Reviewed-by: Tomi Valkeinen +Signed-off-by: Marek Vasut +Reported-by: Laurent Pinchart +Link: https://patch.msgid.link/20251028232959.109936-2-marek.vasut+renesas@mailbox.org +Signed-off-by: Tomi Valkeinen +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +index 76521276e2af8..dd871e17dcf53 100644 +--- a/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h ++++ b/drivers/gpu/drm/renesas/rcar-du/rcar_mipi_dsi_regs.h +@@ -50,8 +50,8 @@ + #define TXCMPPD3R 0x16c + + #define RXSETR 0x200 +-#define RXSETR_CRCEN (((n) & 0xf) << 24) +-#define RXSETR_ECCEN (((n) & 0xf) << 16) ++#define RXSETR_CRCEN(n) (((n) & 0xf) << 24) ++#define RXSETR_ECCEN(n) (((n) & 0xf) << 16) + #define RXPSETR 0x210 + #define RXPSETR_LPPDACC (1 << 0) + #define RXPSR 0x220 +-- +2.51.0 + diff --git a/queue-6.18/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch b/queue-6.18/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch new file mode 100644 index 0000000000..0ac7cdbea4 --- /dev/null +++ b/queue-6.18/drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch @@ -0,0 +1,134 @@ +From 22279349b8d1ff8055676393aea2c1df6a823ac8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:44:22 +0530 +Subject: drm/tidss: Move OLDI mode validation to OLDI bridge mode_valid hook + +From: Jayesh Choudhary + +[ Upstream commit 86db652fc22f5674ffe3b1f7c91c397c69d26d94 ] + +After integrating OLDI support[0], it is necessary to identify which VP +instances use OLDI, since the OLDI driver owns the video port clock +(as a serial clock). Clock operations on these VPs must be delegated to +the OLDI driver, not handled by the TIDSS driver. This issue also +emerged in upstream discussions when DSI-related clock management was +attempted in the TIDSS driver[1]. + +To address this, add an 'is_ext_vp_clk' array to the 'tidss_device' +structure, marking a VP as 'true' during 'tidss_oldi_init()' and as +'false' during 'tidss_oldi_deinit()'. TIDSS then uses 'is_ext_vp_clk' +to skip clock validation checks in 'dispc_vp_mode_valid()' for VPs +under OLDI control. + +Since OLDI uses the DSS VP clock directly as a serial interface and +manages its own rate, mode validation should be implemented in the OLDI +bridge's 'mode_valid' hook. This patch adds that logic, ensuring proper +delegation and avoiding spurious clock handling in the TIDSS driver. + +[0]: https://lore.kernel.org/all/20250528122544.817829-1-aradhya.bhatia@linux.dev/ +[1]: https://lore.kernel.org/all/DA6TT575Z82D.3MPK8HG5GRL8U@kernel.org/ + +Fixes: 7246e0929945 ("drm/tidss: Add OLDI bridge support") +Tested-by: Michael Walle +Reviewed-by: Devarsh Thakkar +Reviewed-by: Tomi Valkeinen +Signed-off-by: Jayesh Choudhary +Signed-off-by: Swamil Jain +Link: https://patch.msgid.link/20251104151422.307162-3-s-jain1@ti.com +Signed-off-by: Tomi Valkeinen +Link: https://patch.msgid.link/ffd5ebe03391b3c01e616c0c844a4b8ddecede36.1762513240.git.jani.nikula@intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 7 +++++++ + drivers/gpu/drm/tidss/tidss_drv.h | 2 ++ + drivers/gpu/drm/tidss/tidss_oldi.c | 22 ++++++++++++++++++++++ + 3 files changed, 31 insertions(+) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 55259b8e87510..6bf1171d0bc2d 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -1313,6 +1313,13 @@ static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, + { + unsigned long round_clock; + ++ /* ++ * For VP's with external clocking, clock operations must be ++ * delegated to respective driver, so we skip the check here. ++ */ ++ if (dispc->tidss->is_ext_vp_clk[hw_videoport]) ++ return 0; ++ + round_clock = clk_round_rate(dispc->vp_clk[hw_videoport], clock); + /* + * To keep the check consistent with dispc_vp_set_clk_rate(), we +diff --git a/drivers/gpu/drm/tidss/tidss_drv.h b/drivers/gpu/drm/tidss/tidss_drv.h +index 84454a4855d11..e1c1f41d8b4be 100644 +--- a/drivers/gpu/drm/tidss/tidss_drv.h ++++ b/drivers/gpu/drm/tidss/tidss_drv.h +@@ -24,6 +24,8 @@ struct tidss_device { + + const struct dispc_features *feat; + struct dispc_device *dispc; ++ bool is_ext_vp_clk[TIDSS_MAX_PORTS]; ++ + + unsigned int num_crtcs; + struct drm_crtc *crtcs[TIDSS_MAX_PORTS]; +diff --git a/drivers/gpu/drm/tidss/tidss_oldi.c b/drivers/gpu/drm/tidss/tidss_oldi.c +index 7688251beba28..17c535bfa0576 100644 +--- a/drivers/gpu/drm/tidss/tidss_oldi.c ++++ b/drivers/gpu/drm/tidss/tidss_oldi.c +@@ -309,6 +309,25 @@ static u32 *tidss_oldi_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + return input_fmts; + } + ++static enum drm_mode_status ++tidss_oldi_mode_valid(struct drm_bridge *bridge, ++ const struct drm_display_info *info, ++ const struct drm_display_mode *mode) ++{ ++ struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); ++ unsigned long round_clock; ++ ++ round_clock = clk_round_rate(oldi->serial, mode->clock * 7 * 1000); ++ /* ++ * To keep the check consistent with dispc_vp_set_clk_rate(), ++ * we use the same 5% check here. ++ */ ++ if (dispc_pclk_diff(mode->clock * 7 * 1000, round_clock) > 5) ++ return -EINVAL; ++ ++ return 0; ++} ++ + static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = { + .attach = tidss_oldi_bridge_attach, + .atomic_pre_enable = tidss_oldi_atomic_pre_enable, +@@ -317,6 +336,7 @@ static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = { + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, ++ .mode_valid = tidss_oldi_mode_valid, + }; + + static int get_oldi_mode(struct device_node *oldi_tx, int *companion_instance) +@@ -430,6 +450,7 @@ void tidss_oldi_deinit(struct tidss_device *tidss) + for (int i = 0; i < tidss->num_oldis; i++) { + if (tidss->oldis[i]) { + drm_bridge_remove(&tidss->oldis[i]->bridge); ++ tidss->is_ext_vp_clk[tidss->oldis[i]->parent_vp] = false; + tidss->oldis[i] = NULL; + } + } +@@ -580,6 +601,7 @@ int tidss_oldi_init(struct tidss_device *tidss) + oldi->bridge.timings = &default_tidss_oldi_timings; + + tidss->oldis[tidss->num_oldis++] = oldi; ++ tidss->is_ext_vp_clk[oldi->parent_vp] = true; + oldi->tidss = tidss; + + drm_bridge_add(&oldi->bridge); +-- +2.51.0 + diff --git a/queue-6.18/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch b/queue-6.18/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch new file mode 100644 index 0000000000..4c0c3496da --- /dev/null +++ b/queue-6.18/drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch @@ -0,0 +1,229 @@ +From d97763daf6ee2d07050c7204e66115fb3a3ae88a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:44:21 +0530 +Subject: drm/tidss: Remove max_pclk_khz and min_pclk_khz from tidss display + features + +From: Jayesh Choudhary + +[ Upstream commit 527e132573dfa793818a536b18eec49598a6f6f5 ] + +The TIDSS hardware does not have independent maximum or minimum pixel +clock limits for each video port. Instead, these limits are determined +by the SoC's clock architecture. Previously, this constraint was +modeled using the 'max_pclk_khz' and 'min_pclk_khz' fields in +'dispc_features', but this approach is static and does not account for +the dynamic behavior of PLLs. + +This patch removes the 'max_pclk_khz' and 'min_pclk_khz' fields from +'dispc_features'. The correct way to check if a requested mode's pixel +clock is supported is by using 'clk_round_rate()' in the 'mode_valid()' +hook. If the best frequency match for the mode clock falls within the +supported tolerance, it is approved. TIDSS supports a 5% pixel clock +tolerance, which is now reflected in the validation logic. + +This change allows existing DSS-compatible drivers to be reused across +SoCs that only differ in their pixel clock characteristics. The +validation uses 'clk_round_rate()' for each mode, which may introduce +additional delay (about 3.5 ms for 30 modes), but this is generally +negligible. Users desiring faster validation may bypass these calls +selectively, for example, checking only the highest resolution mode, +as shown here[1]. + +[1]: https://lore.kernel.org/all/20250704094851.182131-3-j-choudhary@ti.com/ + +Tested-by: Michael Walle +Reviewed-by: Devarsh Thakkar +Reviewed-by: Tomi Valkeinen +Signed-off-by: Jayesh Choudhary +Signed-off-by: Swamil Jain +Link: https://patch.msgid.link/20251104151422.307162-2-s-jain1@ti.com +[Tomi: dropped 'inline' from check_pixel_clock] +Signed-off-by: Tomi Valkeinen +Stable-dep-of: 86db652fc22f ("drm/tidss: Move OLDI mode validation to OLDI bridge mode_valid hook") +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/tidss/tidss_dispc.c | 86 +++++++++++------------------ + drivers/gpu/drm/tidss/tidss_dispc.h | 3 - + 2 files changed, 31 insertions(+), 58 deletions(-) + +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.c b/drivers/gpu/drm/tidss/tidss_dispc.c +index 7c8c15a5c39b3..55259b8e87510 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.c ++++ b/drivers/gpu/drm/tidss/tidss_dispc.c +@@ -57,12 +57,6 @@ static const u16 tidss_k2g_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_k2g_feats = { +- .min_pclk_khz = 4375, +- +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 150000, +- }, +- + /* + * XXX According TRM the RGB input buffer width up to 2560 should + * work on 3 taps, but in practice it only works up to 1280. +@@ -145,11 +139,6 @@ static const u16 tidss_am65x_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_am65x_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- [DISPC_VP_OLDI_AM65X] = 165000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -245,11 +234,6 @@ static const u16 tidss_j721e_common_regs[DISPC_COMMON_REG_TABLE_LEN] = { + }; + + const struct dispc_features dispc_j721e_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 170000, +- [DISPC_VP_INTERNAL] = 600000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 2048, + .in_width_max_3tap_rgb = 4096, +@@ -316,11 +300,6 @@ const struct dispc_features dispc_j721e_feats = { + }; + + const struct dispc_features dispc_am625_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- [DISPC_VP_INTERNAL] = 170000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -377,15 +356,6 @@ const struct dispc_features dispc_am625_feats = { + }; + + const struct dispc_features dispc_am62a7_feats = { +- /* +- * if the code reaches dispc_mode_valid with VP1, +- * it should return MODE_BAD. +- */ +- .max_pclk_khz = { +- [DISPC_VP_TIED_OFF] = 0, +- [DISPC_VP_DPI] = 165000, +- }, +- + .scaling = { + .in_width_max_5tap_rgb = 1280, + .in_width_max_3tap_rgb = 2560, +@@ -442,10 +412,6 @@ const struct dispc_features dispc_am62a7_feats = { + }; + + const struct dispc_features dispc_am62l_feats = { +- .max_pclk_khz = { +- [DISPC_VP_DPI] = 165000, +- }, +- + .subrev = DISPC_AM62L, + + .common = "common", +@@ -1331,33 +1297,54 @@ static void dispc_vp_set_default_color(struct dispc_device *dispc, + DISPC_OVR_DEFAULT_COLOR2, (v >> 32) & 0xffff); + } + ++/* ++ * Calculate the percentage difference between the requested pixel clock rate ++ * and the effective rate resulting from calculating the clock divider value. ++ */ ++unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) ++{ ++ int r = rate / 100, rr = real_rate / 100; ++ ++ return (unsigned int)(abs(((rr - r) * 100) / r)); ++} ++ ++static int check_pixel_clock(struct dispc_device *dispc, u32 hw_videoport, ++ unsigned long clock) ++{ ++ unsigned long round_clock; ++ ++ round_clock = clk_round_rate(dispc->vp_clk[hw_videoport], clock); ++ /* ++ * To keep the check consistent with dispc_vp_set_clk_rate(), we ++ * use the same 5% check here. ++ */ ++ if (dispc_pclk_diff(clock, round_clock) > 5) ++ return -EINVAL; ++ ++ return 0; ++} ++ + enum drm_mode_status dispc_vp_mode_valid(struct dispc_device *dispc, + u32 hw_videoport, + const struct drm_display_mode *mode) + { + u32 hsw, hfp, hbp, vsw, vfp, vbp; + enum dispc_vp_bus_type bus_type; +- int max_pclk; + + bus_type = dispc->feat->vp_bus_type[hw_videoport]; + +- max_pclk = dispc->feat->max_pclk_khz[bus_type]; +- +- if (WARN_ON(max_pclk == 0)) ++ if (WARN_ON(bus_type == DISPC_VP_TIED_OFF)) + return MODE_BAD; + +- if (mode->clock < dispc->feat->min_pclk_khz) +- return MODE_CLOCK_LOW; +- +- if (mode->clock > max_pclk) +- return MODE_CLOCK_HIGH; +- + if (mode->hdisplay > 4096) + return MODE_BAD; + + if (mode->vdisplay > 4096) + return MODE_BAD; + ++ if (check_pixel_clock(dispc, hw_videoport, mode->clock * 1000)) ++ return MODE_CLOCK_RANGE; ++ + /* TODO: add interlace support */ + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + return MODE_NO_INTERLACE; +@@ -1421,17 +1408,6 @@ void dispc_vp_disable_clk(struct dispc_device *dispc, u32 hw_videoport) + clk_disable_unprepare(dispc->vp_clk[hw_videoport]); + } + +-/* +- * Calculate the percentage difference between the requested pixel clock rate +- * and the effective rate resulting from calculating the clock divider value. +- */ +-unsigned int dispc_pclk_diff(unsigned long rate, unsigned long real_rate) +-{ +- int r = rate / 100, rr = real_rate / 100; +- +- return (unsigned int)(abs(((rr - r) * 100) / r)); +-} +- + int dispc_vp_set_clk_rate(struct dispc_device *dispc, u32 hw_videoport, + unsigned long rate) + { +diff --git a/drivers/gpu/drm/tidss/tidss_dispc.h b/drivers/gpu/drm/tidss/tidss_dispc.h +index 60c1b400eb893..42279312dcc1b 100644 +--- a/drivers/gpu/drm/tidss/tidss_dispc.h ++++ b/drivers/gpu/drm/tidss/tidss_dispc.h +@@ -77,9 +77,6 @@ enum dispc_dss_subrevision { + }; + + struct dispc_features { +- int min_pclk_khz; +- int max_pclk_khz[DISPC_VP_MAX_BUS_TYPE]; +- + struct dispc_features_scaling scaling; + + enum dispc_dss_subrevision subrev; +-- +2.51.0 + diff --git a/queue-6.18/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-6.18/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..6b62d72eb4 --- /dev/null +++ b/queue-6.18/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From 224b118ae59c3f9c5a5aec74e27c5e50d98cdc19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index fd76730fd38c0..07db319c3d7f9 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -79,7 +79,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.18/drm-xe-enforce-correct-user-fence-signaling-order-us.patch b/queue-6.18/drm-xe-enforce-correct-user-fence-signaling-order-us.patch new file mode 100644 index 0000000000..699f682b0c --- /dev/null +++ b/queue-6.18/drm-xe-enforce-correct-user-fence-signaling-order-us.patch @@ -0,0 +1,47 @@ +From e0d6df858765e6228a87c8559ccbe6826a1a6fef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:40:45 -0700 +Subject: drm/xe: Enforce correct user fence signaling order using +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Matthew Brost + +[ Upstream commit adda4e855ab6409a3edaa585293f1f2069ab7299 ] + +Prevent application hangs caused by out-of-order fence signaling when +user fences are attached. Use drm_syncobj (via dma-fence-chain) to +guarantee that each user fence signals in order, regardless of the +signaling order of the attached fences. Ensure user fence writebacks to +user space occur in the correct sequence. + +v7: + - Skip drm_syncbj create of error (CI) + +Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") +Signed-off-by: Matthew Brost +Reviewed-by: Thomas Hellström +Link: https://patch.msgid.link/20251031234050.3043507-2-matthew.brost@intel.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/xe/xe_exec_queue.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/gpu/drm/xe/xe_exec_queue.c b/drivers/gpu/drm/xe/xe_exec_queue.c +index cb5f204c08ed6..a6efe4e8ab556 100644 +--- a/drivers/gpu/drm/xe/xe_exec_queue.c ++++ b/drivers/gpu/drm/xe/xe_exec_queue.c +@@ -344,6 +344,9 @@ void xe_exec_queue_destroy(struct kref *ref) + struct xe_exec_queue *q = container_of(ref, struct xe_exec_queue, refcount); + struct xe_exec_queue *eq, *next; + ++ if (q->ufence_syncobj) ++ drm_syncobj_put(q->ufence_syncobj); ++ + if (q->ufence_syncobj) + drm_syncobj_put(q->ufence_syncobj); + +-- +2.51.0 + diff --git a/queue-6.18/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-6.18/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..63dea2697e --- /dev/null +++ b/queue-6.18/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From 71af5c242cc8f807d3c5e8e775c4b649ec5acc71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index 79a21ba0f9fd6..c8258ef403283 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-6.18/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch b/queue-6.18/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch new file mode 100644 index 0000000000..70d358ac8d --- /dev/null +++ b/queue-6.18/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch @@ -0,0 +1,71 @@ +From 0bc3ce6bcfbbff426314647778f194d1699ce5e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:23 +0000 +Subject: efi/libstub: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit 84361123413efc84b06f3441c6c827b95d902732 ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags Bits above the + physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The pgd value is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c +index f1c5fb45d5f7c..c00d0ae7ed5d5 100644 +--- a/drivers/firmware/efi/libstub/x86-5lvl.c ++++ b/drivers/firmware/efi/libstub/x86-5lvl.c +@@ -66,7 +66,7 @@ void efi_5level_switch(void) + bool have_la57 = native_read_cr4() & X86_CR4_LA57; + bool need_toggle = want_la57 ^ have_la57; + u64 *pgt = (void *)la57_toggle + PAGE_SIZE; +- u64 *cr3 = (u64 *)__native_read_cr3(); ++ pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); + u64 *new_cr3; + + if (!la57_toggle || !need_toggle) +@@ -82,7 +82,7 @@ void efi_5level_switch(void) + new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; + } else { + /* take the new root table pointer from the current entry #0 */ +- new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); ++ new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); + + /* copy the new root table if it is not 32-bit addressable */ + if ((u64)new_cr3 > U32_MAX) +-- +2.51.0 + diff --git a/queue-6.18/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch b/queue-6.18/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch new file mode 100644 index 0000000000..bf7199432d --- /dev/null +++ b/queue-6.18/entry-unwind-deferred-fix-unwind_reset_info-placemen.patch @@ -0,0 +1,51 @@ +From 6c146c07917e632f6642e4b4d03a275e9b0dc9a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 11:00:14 +0100 +Subject: entry,unwind/deferred: Fix unwind_reset_info() placement + +From: Peter Zijlstra + +[ Upstream commit cf76553aaa363620f58a6b6409bf544f4bcfa8de ] + +Stephen reported that on KASAN builds he's seeing: + +vmlinux.o: warning: objtool: user_exc_vmm_communication+0x15a: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: exc_debug_user+0x182: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: exc_int3+0x123: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: noist_exc_machine_check+0x17a: call to __kasan_check_read() leaves .noinstr.text section +vmlinux.o: warning: objtool: fred_exc_machine_check+0x17e: call to __kasan_check_read() leaves .noinstr.text section + +This turns out to be atomic ops from unwind_reset_info() that have +explicit instrumentation. Place unwind_reset_info() in the preceding +instrumentation_begin() section. + +Fixes: c6439bfaabf2 ("Merge tag 'trace-deferred-unwind-v6.17' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace") +Reported-by: Stephen Rothwell +Reported-by: Ingo Molnar +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251105100014.GY4068168@noisy.programming.kicks-ass.net +Signed-off-by: Sasha Levin +--- + include/linux/irq-entry-common.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/irq-entry-common.h b/include/linux/irq-entry-common.h +index d643c7c87822e..ba1ed42f8a1c2 100644 +--- a/include/linux/irq-entry-common.h ++++ b/include/linux/irq-entry-common.h +@@ -253,11 +253,11 @@ static __always_inline void exit_to_user_mode_prepare(struct pt_regs *regs) + static __always_inline void exit_to_user_mode(void) + { + instrumentation_begin(); ++ unwind_reset_info(); + trace_hardirqs_on_prepare(); + lockdep_hardirqs_on_prepare(); + instrumentation_end(); + +- unwind_reset_info(); + user_enter_irqoff(); + arch_exit_to_user_mode(); + lockdep_hardirqs_on(CALLER_ADDR0); +-- +2.51.0 + diff --git a/queue-6.18/erofs-correct-fsdax-detection.patch b/queue-6.18/erofs-correct-fsdax-detection.patch new file mode 100644 index 0000000000..fefd0223b9 --- /dev/null +++ b/queue-6.18/erofs-correct-fsdax-detection.patch @@ -0,0 +1,73 @@ +From f06bc9344e9f83e805a7ba3472c122ce88f49430 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 19:57:29 +0800 +Subject: erofs: correct FSDAX detection + +From: Gao Xiang + +[ Upstream commit ebe4f3f6eb0c10f87c58e52a8912694c14fdeda6 ] + +The detection of the primary device is skipped incorrectly +if the multiple or flattened feature is enabled. + +It also fixes the FSDAX misdetection for non-block extra blobs. + +Fixes: c6993c4cb918 ("erofs: Fallback to normal access if DAX is not supported on extra device") +Reported-and-tested-by: syzbot+31b8fb02cb8a25bd5e78@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/r/691af9f6.a70a0220.3124cb.0097.GAE@google.com +Cc: Yuezhang Mo +Reviewed-by: Chao Yu +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/super.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/fs/erofs/super.c b/fs/erofs/super.c +index f3f8d8c066e4e..cd8ff98c29384 100644 +--- a/fs/erofs/super.c ++++ b/fs/erofs/super.c +@@ -174,15 +174,15 @@ static int erofs_init_device(struct erofs_buf *buf, struct super_block *sb, + if (!erofs_is_fileio_mode(sbi)) { + dif->dax_dev = fs_dax_get_by_bdev(file_bdev(file), + &dif->dax_part_off, NULL, NULL); +- if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) { +- erofs_info(sb, "DAX unsupported by %s. Turning off DAX.", +- dif->path); +- clear_opt(&sbi->opt, DAX_ALWAYS); +- } + } else if (!S_ISREG(file_inode(file)->i_mode)) { + fput(file); + return -EINVAL; + } ++ if (!dif->dax_dev && test_opt(&sbi->opt, DAX_ALWAYS)) { ++ erofs_info(sb, "DAX unsupported by %s. Turning off DAX.", ++ dif->path); ++ clear_opt(&sbi->opt, DAX_ALWAYS); ++ } + dif->file = file; + } + +@@ -215,13 +215,13 @@ static int erofs_scan_devices(struct super_block *sb, + ondisk_extradevs, sbi->devs->extra_devices); + return -EINVAL; + } +- if (!ondisk_extradevs) { +- if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) { +- erofs_info(sb, "DAX unsupported by block device. Turning off DAX."); +- clear_opt(&sbi->opt, DAX_ALWAYS); +- } +- return 0; ++ ++ if (test_opt(&sbi->opt, DAX_ALWAYS) && !sbi->dif0.dax_dev) { ++ erofs_info(sb, "DAX unsupported by block device. Turning off DAX."); ++ clear_opt(&sbi->opt, DAX_ALWAYS); + } ++ if (!ondisk_extradevs) ++ return 0; + + if (!sbi->devs->extra_devices && !erofs_is_fscache_mode(sb)) + sbi->devs->flatdev = true; +-- +2.51.0 + diff --git a/queue-6.18/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch b/queue-6.18/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch new file mode 100644 index 0000000000..7df59a0193 --- /dev/null +++ b/queue-6.18/erofs-limit-the-level-of-fs-stacking-for-file-backed.patch @@ -0,0 +1,52 @@ +From 98e82f15503f1a0014e2686d7d8e2b04fd08fea3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 14:23:32 +0800 +Subject: erofs: limit the level of fs stacking for file-backed mounts + +From: Gao Xiang + +[ Upstream commit d53cd891f0e4311889349fff3a784dc552f814b9 ] + +Otherwise, it could cause potential kernel stack overflow (e.g., EROFS +mounting itself). + +Reviewed-by: Sheng Yong +Fixes: fb176750266a ("erofs: add file-backed mount support") +Reviewed-by: Chao Yu +Reviewed-by: Hongbo Li +Signed-off-by: Gao Xiang +Signed-off-by: Sasha Levin +--- + fs/erofs/super.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/fs/erofs/super.c b/fs/erofs/super.c +index cd8ff98c29384..937a215f626c1 100644 +--- a/fs/erofs/super.c ++++ b/fs/erofs/super.c +@@ -639,6 +639,22 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) + + sbi->blkszbits = PAGE_SHIFT; + if (!sb->s_bdev) { ++ /* ++ * (File-backed mounts) EROFS claims it's safe to nest other ++ * fs contexts (including its own) due to self-controlled RO ++ * accesses/contexts and no side-effect changes that need to ++ * context save & restore so it can reuse the current thread ++ * context. However, it still needs to bump `s_stack_depth` to ++ * avoid kernel stack overflow from nested filesystems. ++ */ ++ if (erofs_is_fileio_mode(sbi)) { ++ sb->s_stack_depth = ++ file_inode(sbi->dif0.file)->i_sb->s_stack_depth + 1; ++ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) { ++ erofs_err(sb, "maximum fs stacking depth exceeded"); ++ return -ENOTBLK; ++ } ++ } + sb->s_blocksize = PAGE_SIZE; + sb->s_blocksize_bits = PAGE_SHIFT; + +-- +2.51.0 + diff --git a/queue-6.18/exfat-fix-divide-by-zero-in-exfat_allocate_bitmap.patch b/queue-6.18/exfat-fix-divide-by-zero-in-exfat_allocate_bitmap.patch new file mode 100644 index 0000000000..1b23906ac5 --- /dev/null +++ b/queue-6.18/exfat-fix-divide-by-zero-in-exfat_allocate_bitmap.patch @@ -0,0 +1,39 @@ +From c7eda7cd6f6529bb84fe48002cc060085bf75fba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 11:10:26 +0900 +Subject: exfat: fix divide-by-zero in exfat_allocate_bitmap + +From: Namjae Jeon + +[ Upstream commit d70a5804c563b5e34825353ba9927509df709651 ] + +The variable max_ra_count can be 0 in exfat_allocate_bitmap(), +which causes a divide-by-zero error in the subsequent modulo operation +(i % max_ra_count), leading to a system crash. +When max_ra_count is 0, it means that readahead is not used. This patch +load the bitmap without readahead. + +Fixes: 9fd688678dd8 ("exfat: optimize allocation bitmap loading time") +Reported-by: Jiaming Zhang +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/balloc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/exfat/balloc.c b/fs/exfat/balloc.c +index 2d2d510f2372c..0b6466b3490a0 100644 +--- a/fs/exfat/balloc.c ++++ b/fs/exfat/balloc.c +@@ -106,7 +106,7 @@ static int exfat_allocate_bitmap(struct super_block *sb, + (PAGE_SHIFT - sb->s_blocksize_bits); + for (i = 0; i < sbi->map_sectors; i++) { + /* Trigger the next readahead in advance. */ +- if (0 == (i % max_ra_count)) { ++ if (max_ra_count && 0 == (i % max_ra_count)) { + blk_start_plug(&plug); + for (j = i; j < min(max_ra_count, sbi->map_sectors - i) + i; j++) + sb_breadahead(sb, sector + j); +-- +2.51.0 + diff --git a/queue-6.18/exfat-fix-refcount-leak-in-exfat_find.patch b/queue-6.18/exfat-fix-refcount-leak-in-exfat_find.patch new file mode 100644 index 0000000000..44f3402901 --- /dev/null +++ b/queue-6.18/exfat-fix-refcount-leak-in-exfat_find.patch @@ -0,0 +1,67 @@ +From d31138d71ab18c96c7142a954f3df068c9f5624c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 16:42:28 +0800 +Subject: exfat: fix refcount leak in exfat_find + +From: Shuhao Fu + +[ Upstream commit 9aee8de970f18c2aaaa348e3de86c38e2d956c1d ] + +Fix refcount leaks in `exfat_find` related to `exfat_get_dentry_set`. + +Function `exfat_get_dentry_set` would increase the reference counter of +`es->bh` on success. Therefore, `exfat_put_dentry_set` must be called +after `exfat_get_dentry_set` to ensure refcount consistency. This patch +relocate two checks to avoid possible leaks. + +Fixes: 82ebecdc74ff ("exfat: fix improper check of dentry.stream.valid_size") +Fixes: 13940cef9549 ("exfat: add a check for invalid data size") +Signed-off-by: Shuhao Fu +Reviewed-by: Yuezhang Mo +Signed-off-by: Namjae Jeon +Signed-off-by: Sasha Levin +--- + fs/exfat/namei.c | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/fs/exfat/namei.c b/fs/exfat/namei.c +index 745dce29ddb53..dfe957493d49e 100644 +--- a/fs/exfat/namei.c ++++ b/fs/exfat/namei.c +@@ -645,16 +645,6 @@ static int exfat_find(struct inode *dir, const struct qstr *qname, + info->valid_size = le64_to_cpu(ep2->dentry.stream.valid_size); + info->size = le64_to_cpu(ep2->dentry.stream.size); + +- if (info->valid_size < 0) { +- exfat_fs_error(sb, "data valid size is invalid(%lld)", info->valid_size); +- return -EIO; +- } +- +- if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) { +- exfat_fs_error(sb, "data size is invalid(%lld)", info->size); +- return -EIO; +- } +- + info->start_clu = le32_to_cpu(ep2->dentry.stream.start_clu); + if (!is_valid_cluster(sbi, info->start_clu) && info->size) { + exfat_warn(sb, "start_clu is invalid cluster(0x%x)", +@@ -692,6 +682,16 @@ static int exfat_find(struct inode *dir, const struct qstr *qname, + 0); + exfat_put_dentry_set(&es, false); + ++ if (info->valid_size < 0) { ++ exfat_fs_error(sb, "data valid size is invalid(%lld)", info->valid_size); ++ return -EIO; ++ } ++ ++ if (unlikely(EXFAT_B_TO_CLU_ROUND_UP(info->size, sbi) > sbi->used_clusters)) { ++ exfat_fs_error(sb, "data size is invalid(%lld)", info->size); ++ return -EIO; ++ } ++ + if (ei->start_clu == EXFAT_FREE_CLUSTER) { + exfat_fs_error(sb, + "non-zero size file starts with zero cluster (size : %llu, p_dir : %u, entry : 0x%08x)", +-- +2.51.0 + diff --git a/queue-6.18/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-6.18/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..2a309dae89 --- /dev/null +++ b/queue-6.18/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From 331dae9747a39182ccfa153fa602d11b945fbe11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index 4b091c21908fd..0f4b7c89edd39 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -485,7 +485,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-6.18/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-6.18/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..02e6a9c1d5 --- /dev/null +++ b/queue-6.18/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From e5b8e63723548f62d6e7bad15957df356d83e42d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 9087183602e44..c56b51e1162eb 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -682,6 +682,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -723,15 +741,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -747,15 +756,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-6.18/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-6.18/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..f78debf575 --- /dev/null +++ b/queue-6.18/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From cf205b7105b6a4942746656843e28d6db65b0a8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index aa6cc0a8151ac..83dd31fa1fab5 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -680,7 +680,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -757,6 +757,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-6.18/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-6.18/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..dde1f38ec6 --- /dev/null +++ b/queue-6.18/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From 14541c06ed714e081f29ccd52b8f5c85b485f77f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index 6125cccc9ba79..f2b902e95b738 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-6.18/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch b/queue-6.18/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch new file mode 100644 index 0000000000..f69aabc03b --- /dev/null +++ b/queue-6.18/firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch @@ -0,0 +1,59 @@ +From 5a7f800e605103c75eb821e73b9c98514071e2d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 12:13:23 -0700 +Subject: firmware: qcom: tzmem: fix qcom_tzmem_policy kernel-doc + +From: Randy Dunlap + +[ Upstream commit edd548dc64a699d71ea4f537f815044e763d01e1 ] + +Fix kernel-doc warnings by using correct kernel-doc syntax and +formatting to prevent warnings: + +Warning: include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_STATIC' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_MULTIPLIER' not described in enum 'qcom_tzmem_policy' +Warning: ../include/linux/firmware/qcom/qcom_tzmem.h:25 Enum value + 'QCOM_TZMEM_POLICY_ON_DEMAND' not described in enum 'qcom_tzmem_policy' + +Fixes: 84f5a7b67b61 ("firmware: qcom: add a dedicated TrustZone buffer allocator") +Signed-off-by: Randy Dunlap +Link: https://lore.kernel.org/r/20251017191323.1820167-1-rdunlap@infradead.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + include/linux/firmware/qcom/qcom_tzmem.h | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/include/linux/firmware/qcom/qcom_tzmem.h b/include/linux/firmware/qcom/qcom_tzmem.h +index 48ac0e5454c7f..23173e0c3dddd 100644 +--- a/include/linux/firmware/qcom/qcom_tzmem.h ++++ b/include/linux/firmware/qcom/qcom_tzmem.h +@@ -17,11 +17,20 @@ struct qcom_tzmem_pool; + * enum qcom_tzmem_policy - Policy for pool growth. + */ + enum qcom_tzmem_policy { +- /**< Static pool, never grow above initial size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_STATIC: Static pool, ++ * never grow above initial size. ++ */ + QCOM_TZMEM_POLICY_STATIC = 1, +- /**< When out of memory, add increment * current size of memory. */ ++ /** ++ * @QCOM_TZMEM_POLICY_MULTIPLIER: When out of memory, ++ * add increment * current size of memory. ++ */ + QCOM_TZMEM_POLICY_MULTIPLIER, +- /**< When out of memory add as much as is needed until max_size. */ ++ /** ++ * @QCOM_TZMEM_POLICY_ON_DEMAND: When out of memory ++ * add as much as is needed until max_size. ++ */ + QCOM_TZMEM_POLICY_ON_DEMAND, + }; + +-- +2.51.0 + diff --git a/queue-6.18/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch b/queue-6.18/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch new file mode 100644 index 0000000000..e51a90f25f --- /dev/null +++ b/queue-6.18/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch @@ -0,0 +1,40 @@ +From 51c01ea87bc930284d7159fe960a161520ea68f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:58:13 -0600 +Subject: firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc + +From: Dinh Nguyen + +[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ] + +Fix this warning that was generated from "make htmldocs": + +WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' +not described in 'stratix10_svc' + +Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ +Signed-off-by: Dinh Nguyen +Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/stratix10-svc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index 00f58e27f6de5..deee0e7be34bd 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -52,6 +52,7 @@ struct stratix10_svc_chan; + /** + * struct stratix10_svc - svc private data + * @stratix10_svc_rsu: pointer to stratix10 RSU device ++ * @intel_svc_fcs: pointer to the FCS device + */ + struct stratix10_svc { + struct platform_device *stratix10_svc_rsu; +-- +2.51.0 + diff --git a/queue-6.18/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch b/queue-6.18/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch new file mode 100644 index 0000000000..87b219210c --- /dev/null +++ b/queue-6.18/firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch @@ -0,0 +1,100 @@ +From a2d395d1f44277d4ea1c4929f7b3ba8d64ffa6ff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 13:44:56 +0100 +Subject: firmware: ti_sci: Set IO Isolation only if the firmware is capable + +From: Thomas Richard (TI.com) + +[ Upstream commit 999e9bc953e321651d69556fdd5dfd178f96f128 ] + +Prevent calling ti_sci_cmd_set_io_isolation() on firmware +that does not support the IO_ISOLATION capability. Add the +MSG_FLAG_CAPS_IO_ISOLATION capability flag and check it before +attempting to set IO isolation during suspend/resume operations. + +Without this check, systems with older firmware may experience +undefined behavior or errors when entering/exiting suspend states. + +Fixes: ec24643bdd62 ("firmware: ti_sci: Add system suspend and resume call") +Signed-off-by: Thomas Richard (TI.com) +Reviewed-by: Kevin Hilman +Link: https://patch.msgid.link/20251031-ti-sci-io-isolation-v2-1-60d826b65949@bootlin.com +Signed-off-by: Nishanth Menon +Signed-off-by: Sasha Levin +--- + drivers/firmware/ti_sci.c | 21 +++++++++++++-------- + drivers/firmware/ti_sci.h | 2 ++ + 2 files changed, 15 insertions(+), 8 deletions(-) + +diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c +index 49fd2ae01055d..8d96a3c12b36a 100644 +--- a/drivers/firmware/ti_sci.c ++++ b/drivers/firmware/ti_sci.c +@@ -3751,9 +3751,11 @@ static int __maybe_unused ti_sci_suspend_noirq(struct device *dev) + struct ti_sci_info *info = dev_get_drvdata(dev); + int ret = 0; + +- ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); +- if (ret) +- return ret; ++ if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { ++ ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_ENABLE); ++ if (ret) ++ return ret; ++ } + + return 0; + } +@@ -3767,9 +3769,11 @@ static int __maybe_unused ti_sci_resume_noirq(struct device *dev) + u8 pin; + u8 mode; + +- ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); +- if (ret) +- return ret; ++ if (info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION) { ++ ret = ti_sci_cmd_set_io_isolation(&info->handle, TISCI_MSG_VALUE_IO_DISABLE); ++ if (ret) ++ return ret; ++ } + + ret = ti_sci_msg_cmd_lpm_wake_reason(&info->handle, &source, &time, &pin, &mode); + /* Do not fail to resume on error as the wake reason is not critical */ +@@ -3928,11 +3932,12 @@ static int ti_sci_probe(struct platform_device *pdev) + } + + ti_sci_msg_cmd_query_fw_caps(&info->handle, &info->fw_caps); +- dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s\n", ++ dev_dbg(dev, "Detected firmware capabilities: %s%s%s%s%s\n", + info->fw_caps & MSG_FLAG_CAPS_GENERIC ? "Generic" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_PARTIAL_IO ? " Partial-IO" : "", + info->fw_caps & MSG_FLAG_CAPS_LPM_DM_MANAGED ? " DM-Managed" : "", +- info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "" ++ info->fw_caps & MSG_FLAG_CAPS_LPM_ABORT ? " LPM-Abort" : "", ++ info->fw_caps & MSG_FLAG_CAPS_IO_ISOLATION ? " IO-Isolation" : "" + ); + + ti_sci_setup_ops(info); +diff --git a/drivers/firmware/ti_sci.h b/drivers/firmware/ti_sci.h +index 701c416b2e78f..7559cde17b6cc 100644 +--- a/drivers/firmware/ti_sci.h ++++ b/drivers/firmware/ti_sci.h +@@ -149,6 +149,7 @@ struct ti_sci_msg_req_reboot { + * MSG_FLAG_CAPS_LPM_PARTIAL_IO: Partial IO in LPM + * MSG_FLAG_CAPS_LPM_DM_MANAGED: LPM can be managed by DM + * MSG_FLAG_CAPS_LPM_ABORT: Abort entry to LPM ++ * MSG_FLAG_CAPS_IO_ISOLATION: IO Isolation support + * + * Response to a generic message with message type TI_SCI_MSG_QUERY_FW_CAPS + * providing currently available SOC/firmware capabilities. SoC that don't +@@ -160,6 +161,7 @@ struct ti_sci_msg_resp_query_fw_caps { + #define MSG_FLAG_CAPS_LPM_PARTIAL_IO TI_SCI_MSG_FLAG(4) + #define MSG_FLAG_CAPS_LPM_DM_MANAGED TI_SCI_MSG_FLAG(5) + #define MSG_FLAG_CAPS_LPM_ABORT TI_SCI_MSG_FLAG(9) ++#define MSG_FLAG_CAPS_IO_ISOLATION TI_SCI_MSG_FLAG(7) + #define MSG_MASK_CAPS_LPM GENMASK_ULL(4, 1) + u64 fw_caps; + } __packed; +-- +2.51.0 + diff --git a/queue-6.18/firmware_loader-make-rust_fw_loader_abstractions-sel.patch b/queue-6.18/firmware_loader-make-rust_fw_loader_abstractions-sel.patch new file mode 100644 index 0000000000..092c2c7208 --- /dev/null +++ b/queue-6.18/firmware_loader-make-rust_fw_loader_abstractions-sel.patch @@ -0,0 +1,38 @@ +From c61b0d128843b69688dd04ffd60a2b5f8f31826e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 11:40:54 +0900 +Subject: firmware_loader: make RUST_FW_LOADER_ABSTRACTIONS select FW_LOADER + +From: Alexandre Courbot + +[ Upstream commit 9906efa545d1d2cf25a614eeb219d3f8d5a302cd ] + +The use of firmware_loader is an implementation detail of drivers rather +than a dependency. FW_LOADER is typically selected rather than depended +on; the Rust abstractions should do the same thing. + +Fixes: de6582833db0 ("rust: add firmware abstractions") +Signed-off-by: Alexandre Courbot +Link: https://patch.msgid.link/20251106-b4-select-rust-fw-v3-1-771172257755@nvidia.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/base/firmware_loader/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/base/firmware_loader/Kconfig b/drivers/base/firmware_loader/Kconfig +index 752b9a9bea038..15eff8a4b5053 100644 +--- a/drivers/base/firmware_loader/Kconfig ++++ b/drivers/base/firmware_loader/Kconfig +@@ -38,7 +38,7 @@ config FW_LOADER_DEBUG + config RUST_FW_LOADER_ABSTRACTIONS + bool "Rust Firmware Loader abstractions" + depends on RUST +- depends on FW_LOADER=y ++ select FW_LOADER + help + This enables the Rust abstractions for the firmware loader API. + +-- +2.51.0 + diff --git a/queue-6.18/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch b/queue-6.18/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch new file mode 100644 index 0000000000..d290a0724e --- /dev/null +++ b/queue-6.18/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch @@ -0,0 +1,104 @@ +From 7dd4d8bba5bb65ba4a74a06a3d500aaab6d9ac04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 23:56:30 +0000 +Subject: fs/9p: Don't open remote file with APPEND mode when writeback cache + is used + +From: Tingmao Wang + +[ Upstream commit a63dd8fd137933551bfd9aeeeaa942f04c7aad65 ] + +When page cache is used, writebacks are done on a page granularity, and it +is expected that the underlying filesystem (such as v9fs) should respect +the write position. However, currently v9fs will passthrough O_APPEND to +the server even on cached mode. This causes data corruption if a sync or +fstat gets between two writes to the same file. + +This patch removes the APPEND flag from the open request we send to the +server when writeback caching is involved. I believe keeping server-side +APPEND is probably fine for uncached mode (even if two fds are opened, one +without O_APPEND and one with it, this should still be fine since they +would use separate fid for the writes). + +Signed-off-by: Tingmao Wang +Fixes: 4eb3117888a9 ("fs/9p: Rework cache modes and add new options to Documentation") +Message-ID: <20251102235631.8724-1-m@maowtm.org> +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/vfs_file.c | 11 ++++++++--- + fs/9p/vfs_inode.c | 3 +-- + fs/9p/vfs_inode_dotl.c | 2 +- + 3 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c +index eb0b083da269b..d1db03093d4c3 100644 +--- a/fs/9p/vfs_file.c ++++ b/fs/9p/vfs_file.c +@@ -43,14 +43,18 @@ int v9fs_file_open(struct inode *inode, struct file *file) + struct v9fs_session_info *v9ses; + struct p9_fid *fid; + int omode; ++ int o_append; + + p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); + v9ses = v9fs_inode2v9ses(inode); +- if (v9fs_proto_dotl(v9ses)) ++ if (v9fs_proto_dotl(v9ses)) { + omode = v9fs_open_to_dotl_flags(file->f_flags); +- else ++ o_append = P9_DOTL_APPEND; ++ } else { + omode = v9fs_uflags2omode(file->f_flags, + v9fs_proto_dotu(v9ses)); ++ o_append = P9_OAPPEND; ++ } + fid = file->private_data; + if (!fid) { + fid = v9fs_fid_clone(file_dentry(file)); +@@ -58,9 +62,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) + return PTR_ERR(fid); + + if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { +- int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; ++ int writeback_omode = (omode & ~(P9_OWRITE | o_append)) | P9_ORDWR; + + p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); ++ + err = p9_client_open(fid, writeback_omode); + if (err < 0) { + p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index d0c77ec31b1dd..0f3189a0a516a 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -786,7 +786,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, + p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_OAPPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +@@ -1393,4 +1393,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = { + .getattr = v9fs_vfs_getattr, + .setattr = v9fs_vfs_setattr, + }; +- +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index be297e3354688..6312b3590f743 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -282,7 +282,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, + } + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_DOTL_APPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +-- +2.51.0 + diff --git a/queue-6.18/fs-lift-the-fmode_nocmtime-check-into-file_update_ti.patch b/queue-6.18/fs-lift-the-fmode_nocmtime-check-into-file_update_ti.patch new file mode 100644 index 0000000000..a181705c0b --- /dev/null +++ b/queue-6.18/fs-lift-the-fmode_nocmtime-check-into-file_update_ti.patch @@ -0,0 +1,59 @@ +From e6138612392c4063c9aa57991ec6a45467366577 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 07:47:23 +0100 +Subject: fs: lift the FMODE_NOCMTIME check into file_update_time_flags + +From: Christoph Hellwig + +[ Upstream commit 7f30e7a42371af4bba53f9a875a0d320cead9f4b ] + +FMODE_NOCMTIME used to be just a hack for the legacy XFS handle-based +"invisible I/O", but commit e5e9b24ab8fa ("nfsd: freeze c/mtime updates +with outstanding WRITE_ATTRS delegation") started using it from +generic callers. + +I'm not sure other file systems are actually read for this in general, +so the above commit should get a closer look, but for it to make any +sense, file_update_time needs to respect the flag. + +Lift the check from file_modified_flags to file_update_time so that +users of file_update_time inherit the behavior and so that all the +checks are done in one place. + +Fixes: e5e9b24ab8fa ("nfsd: freeze c/mtime updates with outstanding WRITE_ATTRS delegation") +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251120064859.2911749-3-hch@lst.de +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Jeff Layton +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/inode.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/inode.c b/fs/inode.c +index 540f4a28c202d..2c55ec49b0239 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -2332,6 +2332,8 @@ static int file_update_time_flags(struct file *file, unsigned int flags) + /* First try to exhaust all avenues to not sync */ + if (IS_NOCMTIME(inode)) + return 0; ++ if (unlikely(file->f_mode & FMODE_NOCMTIME)) ++ return 0; + + now = current_time(inode); + +@@ -2403,8 +2405,6 @@ static int file_modified_flags(struct file *file, int flags) + ret = file_remove_privs_flags(file, flags); + if (ret) + return ret; +- if (unlikely(file->f_mode & FMODE_NOCMTIME)) +- return 0; + return file_update_time_flags(file, flags); + } + +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-initialize-allocated-memory-before-use.patch b/queue-6.18/fs-ntfs3-initialize-allocated-memory-before-use.patch new file mode 100644 index 0000000000..17c01c3fa1 --- /dev/null +++ b/queue-6.18/fs-ntfs3-initialize-allocated-memory-before-use.patch @@ -0,0 +1,76 @@ +From 1d8839e06cbabe2b79fb6bca765a50a16618097f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 22:18:08 +0100 +Subject: fs/ntfs3: Initialize allocated memory before use + +From: Bartlomiej Kubik + +[ Upstream commit a8a3ca23bbd9d849308a7921a049330dc6c91398 ] + +KMSAN reports: Multiple uninitialized values detected: + +- KMSAN: uninit-value in ntfs_read_hdr (3) +- KMSAN: uninit-value in bcmp (3) + +Memory is allocated by __getname(), which is a wrapper for +kmem_cache_alloc(). This memory is used before being properly +cleared. Change kmem_cache_alloc() to kmem_cache_zalloc() to +properly allocate and clear memory before use. + +Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") +Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") +Tested-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=332bd4e9d148f11a87dc + +Fixes: 82cae269cfa9 ("fs/ntfs3: Add initialization of super block") +Fixes: 78ab59fee07f ("fs/ntfs3: Rework file operations") +Tested-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com +Reported-by: syzbot+0399100e525dd9696764@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=0399100e525dd9696764 + +Reviewed-by: Khalid Aziz +Signed-off-by: Bartlomiej Kubik +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 05004f8880ce6..164fd63dff40d 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1279,7 +1279,7 @@ int ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir, + fa |= FILE_ATTRIBUTE_READONLY; + + /* Allocate PATH_MAX bytes. */ +- new_de = __getname(); ++ new_de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!new_de) { + err = -ENOMEM; + goto out1; +@@ -1720,10 +1720,9 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + struct NTFS_DE *de; + + /* Allocate PATH_MAX bytes. */ +- de = __getname(); ++ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!de) + return -ENOMEM; +- memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +@@ -1759,7 +1758,7 @@ int ntfs_unlink_inode(struct inode *dir, const struct dentry *dentry) + return -EINVAL; + + /* Allocate PATH_MAX bytes. */ +- de = __getname(); ++ de = kmem_cache_zalloc(names_cachep, GFP_KERNEL); + if (!de) + return -ENOMEM; + +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-6.18/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..a736c318c7 --- /dev/null +++ b/queue-6.18/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From 9dd952f234b47dd7f3872ed05e62c44da15aaaa1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 8f9fe1d7a6908..a557e3ec0d4c4 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1015,9 +1015,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-6.18/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-6.18/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..3b8cab64bf --- /dev/null +++ b/queue-6.18/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From 60eb8cc3520d69237fa08dd0ff04b89f61679806 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index a557e3ec0d4c4..e5a005d216f31 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -325,8 +325,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.18/fs-refactor-file-timestamp-update-logic.patch b/queue-6.18/fs-refactor-file-timestamp-update-logic.patch new file mode 100644 index 0000000000..762da5e2c6 --- /dev/null +++ b/queue-6.18/fs-refactor-file-timestamp-update-logic.patch @@ -0,0 +1,133 @@ +From 9f2845110ba2ada5939f1d913cb86001b26954f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 07:47:22 +0100 +Subject: fs: refactor file timestamp update logic + +From: Christoph Hellwig + +[ Upstream commit 3cd9a42f1b5e34d3972237cbf8541af60844cbd4 ] + +Currently the two high-level APIs use two helper functions to implement +almost all of the logic. Refactor the two helpers and the common logic +into a new file_update_time_flags routine that gets the iocb flags or +0 in case of file_update_time passed so that the entire logic is +contained in a single function and can be easily understood and modified. + +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251120064859.2911749-2-hch@lst.de +Reviewed-by: Chaitanya Kulkarni +Reviewed-by: Jeff Layton +Reviewed-by: Jan Kara +Signed-off-by: Christian Brauner +Stable-dep-of: 7f30e7a42371 ("fs: lift the FMODE_NOCMTIME check into file_update_time_flags") +Signed-off-by: Sasha Levin +--- + fs/inode.c | 54 +++++++++++++++++------------------------------------- + 1 file changed, 17 insertions(+), 37 deletions(-) + +diff --git a/fs/inode.c b/fs/inode.c +index cff1d3af0d577..540f4a28c202d 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -2322,10 +2322,12 @@ struct timespec64 current_time(struct inode *inode) + } + EXPORT_SYMBOL(current_time); + +-static int inode_needs_update_time(struct inode *inode) ++static int file_update_time_flags(struct file *file, unsigned int flags) + { ++ struct inode *inode = file_inode(file); + struct timespec64 now, ts; +- int sync_it = 0; ++ int sync_mode = 0; ++ int ret = 0; + + /* First try to exhaust all avenues to not sync */ + if (IS_NOCMTIME(inode)) +@@ -2335,29 +2337,23 @@ static int inode_needs_update_time(struct inode *inode) + + ts = inode_get_mtime(inode); + if (!timespec64_equal(&ts, &now)) +- sync_it |= S_MTIME; +- ++ sync_mode |= S_MTIME; + ts = inode_get_ctime(inode); + if (!timespec64_equal(&ts, &now)) +- sync_it |= S_CTIME; +- ++ sync_mode |= S_CTIME; + if (IS_I_VERSION(inode) && inode_iversion_need_inc(inode)) +- sync_it |= S_VERSION; ++ sync_mode |= S_VERSION; + +- return sync_it; +-} +- +-static int __file_update_time(struct file *file, int sync_mode) +-{ +- int ret = 0; +- struct inode *inode = file_inode(file); ++ if (!sync_mode) ++ return 0; + +- /* try to update time settings */ +- if (!mnt_get_write_access_file(file)) { +- ret = inode_update_time(inode, sync_mode); +- mnt_put_write_access_file(file); +- } ++ if (flags & IOCB_NOWAIT) ++ return -EAGAIN; + ++ if (mnt_get_write_access_file(file)) ++ return 0; ++ ret = inode_update_time(inode, sync_mode); ++ mnt_put_write_access_file(file); + return ret; + } + +@@ -2377,14 +2373,7 @@ static int __file_update_time(struct file *file, int sync_mode) + */ + int file_update_time(struct file *file) + { +- int ret; +- struct inode *inode = file_inode(file); +- +- ret = inode_needs_update_time(inode); +- if (ret <= 0) +- return ret; +- +- return __file_update_time(file, ret); ++ return file_update_time_flags(file, 0); + } + EXPORT_SYMBOL(file_update_time); + +@@ -2406,7 +2395,6 @@ EXPORT_SYMBOL(file_update_time); + static int file_modified_flags(struct file *file, int flags) + { + int ret; +- struct inode *inode = file_inode(file); + + /* + * Clear the security bits if the process is not being run by root. +@@ -2415,17 +2403,9 @@ static int file_modified_flags(struct file *file, int flags) + ret = file_remove_privs_flags(file, flags); + if (ret) + return ret; +- + if (unlikely(file->f_mode & FMODE_NOCMTIME)) + return 0; +- +- ret = inode_needs_update_time(inode); +- if (ret <= 0) +- return ret; +- if (flags & IOCB_NOWAIT) +- return -EAGAIN; +- +- return __file_update_time(file, ret); ++ return file_update_time_flags(file, flags); + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch b/queue-6.18/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch new file mode 100644 index 0000000000..2bed7b8a0c --- /dev/null +++ b/queue-6.18/fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch @@ -0,0 +1,83 @@ +From cd34a7debb1f41d6ef6dd4bdc266d540e8098315 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Oct 2025 02:38:43 -0400 +Subject: fuse_ctl_add_conn(): fix nlink breakage in case of early failure + +From: Al Viro + +[ Upstream commit c460192aae197df1b4db1dca493c35ad529f1b64 ] + +fuse_ctl_remove_conn() used to decrement the link count of root +manually; that got subsumed by simple_recursive_removal(), but +in case when subdirectory creation has failed the latter won't +get called. + +Just move the modification of parent's link count into +fuse_ctl_add_dentry() to keep the things simple. Allows to +get rid of the nlink argument as well... + +Fixes: fcaac5b42768 "fuse_ctl: use simple_recursive_removal()" +Acked-by: Miklos Szeredi +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/fuse/control.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +diff --git a/fs/fuse/control.c b/fs/fuse/control.c +index bb407705603c2..5247df896c5d0 100644 +--- a/fs/fuse/control.c ++++ b/fs/fuse/control.c +@@ -205,8 +205,7 @@ static const struct file_operations fuse_conn_congestion_threshold_ops = { + + static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, + struct fuse_conn *fc, +- const char *name, +- int mode, int nlink, ++ const char *name, int mode, + const struct inode_operations *iop, + const struct file_operations *fop) + { +@@ -232,7 +231,10 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent, + if (iop) + inode->i_op = iop; + inode->i_fop = fop; +- set_nlink(inode, nlink); ++ if (S_ISDIR(mode)) { ++ inc_nlink(d_inode(parent)); ++ inc_nlink(inode); ++ } + inode->i_private = fc; + d_add(dentry, inode); + +@@ -252,22 +254,21 @@ int fuse_ctl_add_conn(struct fuse_conn *fc) + return 0; + + parent = fuse_control_sb->s_root; +- inc_nlink(d_inode(parent)); + sprintf(name, "%u", fc->dev); +- parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, 2, ++ parent = fuse_ctl_add_dentry(parent, fc, name, S_IFDIR | 0500, + &simple_dir_inode_operations, + &simple_dir_operations); + if (!parent) + goto err; + +- if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, 1, ++ if (!fuse_ctl_add_dentry(parent, fc, "waiting", S_IFREG | 0400, + NULL, &fuse_ctl_waiting_ops) || +- !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, 1, ++ !fuse_ctl_add_dentry(parent, fc, "abort", S_IFREG | 0200, + NULL, &fuse_ctl_abort_ops) || + !fuse_ctl_add_dentry(parent, fc, "max_background", S_IFREG | 0600, +- 1, NULL, &fuse_conn_max_background_ops) || ++ NULL, &fuse_conn_max_background_ops) || + !fuse_ctl_add_dentry(parent, fc, "congestion_threshold", +- S_IFREG | 0600, 1, NULL, ++ S_IFREG | 0600, NULL, + &fuse_conn_congestion_threshold_ops)) + goto err; + +-- +2.51.0 + diff --git a/queue-6.18/gfs2-prevent-recursive-memory-reclaim.patch b/queue-6.18/gfs2-prevent-recursive-memory-reclaim.patch new file mode 100644 index 0000000000..5f789e6c25 --- /dev/null +++ b/queue-6.18/gfs2-prevent-recursive-memory-reclaim.patch @@ -0,0 +1,135 @@ +From 7f166215e9a39c9cb048c4cc061324f1bf72761a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:05:37 +0000 +Subject: gfs2: Prevent recursive memory reclaim + +From: Andreas Gruenbacher + +[ Upstream commit 2c5f4a53476e3cab70adc77b38942c066bd2c17c ] + +Function new_inode() returns a new inode with inode->i_mapping->gfp_mask +set to GFP_HIGHUSER_MOVABLE. This value includes the __GFP_FS flag, so +allocations in that address space can recurse into filesystem memory +reclaim. We don't want that to happen because it can consume a +significant amount of stack memory. + +Worse than that is that it can also deadlock: for example, in several +places, gfs2_unstuff_dinode() is called inside filesystem transactions. +This calls filemap_grab_folio(), which can allocate a new folio, which +can trigger memory reclaim. If memory reclaim recurses into the +filesystem and starts another transaction, a deadlock will ensue. + +To fix these kinds of problems, prevent memory reclaim from recursing +into filesystem code by making sure that the gfp_mask of inode address +spaces doesn't include __GFP_FS. + +The "meta" and resource group address spaces were already using GFP_NOFS +as their gfp_mask (which doesn't include __GFP_FS). The default value +of GFP_HIGHUSER_MOVABLE is less restrictive than GFP_NOFS, though. To +avoid being overly limiting, use the default value and only knock off +the __GFP_FS flag. I'm not sure if this will actually make a +difference, but it also shouldn't hurt. + +This patch is loosely based on commit ad22c7a043c2 ("xfs: prevent stack +overflows from page cache allocation"). + +Fixes xfstest generic/273. + +Fixes: dc0b9435238c ("gfs: Don't use GFP_NOFS in gfs2_unstuff_dinode") +Reviewed-by: Andrew Price +Signed-off-by: Andreas Gruenbacher +Signed-off-by: Sasha Levin +--- + fs/gfs2/glock.c | 5 ++++- + fs/gfs2/inode.c | 15 +++++++++++++++ + fs/gfs2/inode.h | 1 + + fs/gfs2/ops_fstype.c | 2 +- + 4 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c +index b677c0e6b9ab3..9f2eb7e385695 100644 +--- a/fs/gfs2/glock.c ++++ b/fs/gfs2/glock.c +@@ -1211,10 +1211,13 @@ int gfs2_glock_get(struct gfs2_sbd *sdp, u64 number, + + mapping = gfs2_glock2aspace(gl); + if (mapping) { ++ gfp_t gfp_mask; ++ + mapping->a_ops = &gfs2_meta_aops; + mapping->host = sdp->sd_inode; + mapping->flags = 0; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfp_mask = mapping_gfp_mask(sdp->sd_inode->i_mapping); ++ mapping_set_gfp_mask(mapping, gfp_mask); + mapping->i_private_data = NULL; + mapping->writeback_index = 0; + } +diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c +index 8a7ed80d9f2d6..d7e35a05c1610 100644 +--- a/fs/gfs2/inode.c ++++ b/fs/gfs2/inode.c +@@ -89,6 +89,19 @@ static int iget_set(struct inode *inode, void *opaque) + return 0; + } + ++void gfs2_setup_inode(struct inode *inode) ++{ ++ gfp_t gfp_mask; ++ ++ /* ++ * Ensure all page cache allocations are done from GFP_NOFS context to ++ * prevent direct reclaim recursion back into the filesystem and blowing ++ * stacks or deadlocking. ++ */ ++ gfp_mask = mapping_gfp_mask(inode->i_mapping); ++ mapping_set_gfp_mask(inode->i_mapping, gfp_mask & ~__GFP_FS); ++} ++ + /** + * gfs2_inode_lookup - Lookup an inode + * @sb: The super block +@@ -132,6 +145,7 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type, + struct gfs2_glock *io_gl; + int extra_flags = 0; + ++ gfs2_setup_inode(inode); + error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, + &ip->i_gl); + if (unlikely(error)) +@@ -752,6 +766,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, + error = -ENOMEM; + if (!inode) + goto fail_gunlock; ++ gfs2_setup_inode(inode); + ip = GFS2_I(inode); + + error = posix_acl_create(dir, &mode, &default_acl, &acl); +diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h +index e43f08eb26e72..2fcd96dd13613 100644 +--- a/fs/gfs2/inode.h ++++ b/fs/gfs2/inode.h +@@ -86,6 +86,7 @@ static inline int gfs2_check_internal_file_size(struct inode *inode, + return -EIO; + } + ++void gfs2_setup_inode(struct inode *inode); + struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned type, + u64 no_addr, u64 no_formal_ino, + unsigned int blktype); +diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c +index aa15183f9a168..1a2db8053da04 100644 +--- a/fs/gfs2/ops_fstype.c ++++ b/fs/gfs2/ops_fstype.c +@@ -1183,7 +1183,7 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc) + + mapping = gfs2_aspace(sdp); + mapping->a_ops = &gfs2_rgrp_aops; +- mapping_set_gfp_mask(mapping, GFP_NOFS); ++ gfs2_setup_inode(sdp->sd_inode); + + error = init_names(sdp, silent); + if (error) +-- +2.51.0 + diff --git a/queue-6.18/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-6.18/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..fea5b93066 --- /dev/null +++ b/queue-6.18/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 91c312029b622708c36afeaf98676b3c8462b273 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index f63d14a57a1d9..acc7d82e0585e 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -345,8 +345,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -369,7 +367,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-6.18/gpu-nova-core-gsp-do-not-unwrap-sgentry.patch b/queue-6.18/gpu-nova-core-gsp-do-not-unwrap-sgentry.patch new file mode 100644 index 0000000000..76a6a9c0a5 --- /dev/null +++ b/queue-6.18/gpu-nova-core-gsp-do-not-unwrap-sgentry.patch @@ -0,0 +1,43 @@ +From c44ffeb7e540fccca6e53b10b7971e27084e77c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 15:05:53 +0200 +Subject: gpu: nova-core: gsp: do not unwrap() SGEntry + +From: Danilo Krummrich + +[ Upstream commit f7a33a67c50c92589b046e69b9075b7d28d31f87 ] + +Don't use unwrap() to extract an Option, instead handle the +error condition gracefully. + +Fixes: a841614e607c ("gpu: nova-core: firmware: process and prepare the GSP firmware") +Signed-off-by: Danilo Krummrich +Reviewed-by: John Hubbard +Signed-off-by: Alexandre Courbot +Message-ID: <20250926130623.61316-2-dakr@kernel.org> +Signed-off-by: Sasha Levin +--- + drivers/gpu/nova-core/firmware/gsp.rs | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs +index ca785860e1c82..6b0761460a57d 100644 +--- a/drivers/gpu/nova-core/firmware/gsp.rs ++++ b/drivers/gpu/nova-core/firmware/gsp.rs +@@ -202,9 +202,10 @@ pub(crate) fn new<'a, 'b>( + let mut level0_data = kvec![0u8; GSP_PAGE_SIZE]?; + + // Fill level 1 page entry. +- let level1_entry = level1.iter().next().unwrap().dma_address(); +- let dst = &mut level0_data[..size_of_val(&level1_entry)]; +- dst.copy_from_slice(&level1_entry.to_le_bytes()); ++ let level1_entry = level1.iter().next().ok_or(EINVAL)?; ++ let level1_entry_addr = level1_entry.dma_address(); ++ let dst = &mut level0_data[..size_of_val(&level1_entry_addr)]; ++ dst.copy_from_slice(&level1_entry_addr.to_le_bytes()); + + // Turn the level0 page table into a [`DmaObject`]. + DmaObject::from_data(dev, &level0_data)? +-- +2.51.0 + diff --git a/queue-6.18/gpu-nova-core-gsp-remove-useless-conversion.patch b/queue-6.18/gpu-nova-core-gsp-remove-useless-conversion.patch new file mode 100644 index 0000000000..6fb6919c9e --- /dev/null +++ b/queue-6.18/gpu-nova-core-gsp-remove-useless-conversion.patch @@ -0,0 +1,40 @@ +From 93cbf6d57c78ba3fe3fe27ee771a63b18979784d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 15:05:52 +0200 +Subject: gpu: nova-core: gsp: remove useless conversion + +From: Danilo Krummrich + +[ Upstream commit 87990025b87283f1b8c50d4d75379ca6d86d2211 ] + +Because nova-core depends on CONFIG_64BIT and a raw DmaAddress is +always a u64, we can remove the now actually useless conversion. + +Signed-off-by: Danilo Krummrich +Reviewed-by: John Hubbard +[acourbot@nvidia.com: reword commit as suggested by John.] +Signed-off-by: Alexandre Courbot +Message-ID: <20250926130623.61316-1-dakr@kernel.org> +Stable-dep-of: f7a33a67c50c ("gpu: nova-core: gsp: do not unwrap() SGEntry") +Signed-off-by: Sasha Levin +--- + drivers/gpu/nova-core/firmware/gsp.rs | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/gpu/nova-core/firmware/gsp.rs b/drivers/gpu/nova-core/firmware/gsp.rs +index 9b70095434c61..ca785860e1c82 100644 +--- a/drivers/gpu/nova-core/firmware/gsp.rs ++++ b/drivers/gpu/nova-core/firmware/gsp.rs +@@ -202,8 +202,7 @@ pub(crate) fn new<'a, 'b>( + let mut level0_data = kvec![0u8; GSP_PAGE_SIZE]?; + + // Fill level 1 page entry. +- #[allow(clippy::useless_conversion)] +- let level1_entry = u64::from(level1.iter().next().unwrap().dma_address()); ++ let level1_entry = level1.iter().next().unwrap().dma_address(); + let dst = &mut level0_data[..size_of_val(&level1_entry)]; + dst.copy_from_slice(&level1_entry.to_le_bytes()); + +-- +2.51.0 + diff --git a/queue-6.18/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch b/queue-6.18/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch new file mode 100644 index 0000000000..0c91de773b --- /dev/null +++ b/queue-6.18/greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch @@ -0,0 +1,66 @@ +From 3c5d6fc8764200efe7db456b6883cc96b541fd72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:40:27 +0800 +Subject: greybus: gb-beagleplay: Fix timeout handling in bootloader functions + +From: Haotian Zhang + +[ Upstream commit e6df0f649cff08da7a2feb6d963b39076ca129f9 ] + +wait_for_completion_timeout() returns the remaining jiffies +(at least 1) on success or 0 on timeout, but never negative +error codes. The current code incorrectly checks for negative +values, causing timeouts to be ignored and treated as success. + +Check for a zero return value to correctly identify and +handle timeout events. + +Fixes: 0cf7befa3ea2 ("greybus: gb-beagleplay: Add firmware upload API") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251121064027.571-1-vulab@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/greybus/gb-beagleplay.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/greybus/gb-beagleplay.c b/drivers/greybus/gb-beagleplay.c +index 9610f878da1b6..87186f891a6ac 100644 +--- a/drivers/greybus/gb-beagleplay.c ++++ b/drivers/greybus/gb-beagleplay.c +@@ -644,8 +644,8 @@ static int cc1352_bootloader_wait_for_ack(struct gb_beagleplay *bg) + + ret = wait_for_completion_timeout( + &bg->fwl_ack_com, msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire ack semaphore"); + + switch (READ_ONCE(bg->fwl_ack)) { +@@ -683,8 +683,8 @@ static int cc1352_bootloader_get_status(struct gb_beagleplay *bg) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + switch (READ_ONCE(bg->fwl_cmd_response)) { +@@ -768,8 +768,8 @@ static int cc1352_bootloader_crc32(struct gb_beagleplay *bg, u32 *crc32) + ret = wait_for_completion_timeout( + &bg->fwl_cmd_response_com, + msecs_to_jiffies(CC1352_BOOTLOADER_TIMEOUT)); +- if (ret < 0) +- return dev_err_probe(&bg->sd->dev, ret, ++ if (!ret) ++ return dev_err_probe(&bg->sd->dev, -ETIMEDOUT, + "Failed to acquire last status semaphore"); + + *crc32 = READ_ONCE(bg->fwl_cmd_response); +-- +2.51.0 + diff --git a/queue-6.18/hfs-fix-potential-use-after-free-in-hfs_correct_next.patch b/queue-6.18/hfs-fix-potential-use-after-free-in-hfs_correct_next.patch new file mode 100644 index 0000000000..eacfa1ec18 --- /dev/null +++ b/queue-6.18/hfs-fix-potential-use-after-free-in-hfs_correct_next.patch @@ -0,0 +1,42 @@ +From 685a45b838dd5a8de271182b172dd7276edb6743 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:30:43 +0300 +Subject: hfs: fix potential use after free in hfs_correct_next_unused_CNID() + +From: Dan Carpenter + +[ Upstream commit c105e76bb17cf4b55fe89c6ad4f6a0e3972b5b08 ] + +This code calls hfs_bnode_put(node) which drops the refcount and then +dreferences "node" on the next line. It's only safe to use "node" +when we're holding a reference so flip these two lines around. + +Fixes: a06ec283e125 ("hfs: add logic of correcting a next unused CNID") +Signed-off-by: Dan Carpenter +Reviewed-by: Viacheslav Dubeyko +Signed-off-by: Viacheslav Dubeyko +Link: https://lore.kernel.org/r/aN-Xw8KnbSnuIcLk@stanley.mountain +Signed-off-by: Viacheslav Dubeyko +Signed-off-by: Sasha Levin +--- + fs/hfs/catalog.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/hfs/catalog.c b/fs/hfs/catalog.c +index caebabb6642f1..b80ba40e38776 100644 +--- a/fs/hfs/catalog.c ++++ b/fs/hfs/catalog.c +@@ -322,9 +322,9 @@ int hfs_correct_next_unused_CNID(struct super_block *sb, u32 cnid) + } + } + ++ node_id = node->prev; + hfs_bnode_put(node); + +- node_id = node->prev; + } while (node_id >= leaf_head); + + return -ENOENT; +-- +2.51.0 + diff --git a/queue-6.18/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch b/queue-6.18/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch new file mode 100644 index 0000000000..3408f8effc --- /dev/null +++ b/queue-6.18/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch @@ -0,0 +1,59 @@ +From a128142f447d7d47963f081afafb370c4ecdda8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 19:30:58 +0000 +Subject: HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync() + +From: Mavroudis Chatzilazaridis + +[ Upstream commit aba7963544d47d82cdf36602a6678a093af0299d ] + +Currently, hidpp_send_message_sync() retries sending the message when the +device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which +has a different meaning under RAP. This ends up being a problem because +this function is used for both FAP and RAP messages. + +This issue is not noticeable on older receivers with unreachable devices +since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to +HIDPP20_ERROR_BUSY (0x08). + +However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which +happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when +the device is not actually busy. + +This is resolved by checking if the error response is FAP or RAP and +picking the respective ERROR_BUSY code. + +Fixes: 60165ab774cb ("HID: logitech-hidpp: rework one more time the retries attempts") +Signed-off-by: Mavroudis Chatzilazaridis +Tested-by: Stuart Hayhurst +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 5e763de4b94fd..a88f2e5f791c6 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -352,10 +352,15 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, + + do { + ret = __do_hidpp_send_message_sync(hidpp, message, response); +- if (ret != HIDPP20_ERROR_BUSY) ++ if (response->report_id == REPORT_ID_HIDPP_SHORT && ++ ret != HIDPP_ERROR_BUSY) ++ break; ++ if ((response->report_id == REPORT_ID_HIDPP_LONG || ++ response->report_id == REPORT_ID_HIDPP_VERY_LONG) && ++ ret != HIDPP20_ERROR_BUSY) + break; + +- dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret); ++ dbg_hid("%s:got busy hidpp error %02X, retrying\n", __func__, ret); + } while (--max_retries); + + mutex_unlock(&hidpp->send_mutex); +-- +2.51.0 + diff --git a/queue-6.18/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch b/queue-6.18/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch new file mode 100644 index 0000000000..5c2fbbd187 --- /dev/null +++ b/queue-6.18/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch @@ -0,0 +1,54 @@ +From 7ed0bd766a98e6cb737f1911ac91c4520e6d17f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 00:26:02 +0800 +Subject: hwmon: sy7636a: Fix regulator_enable resource leak on error path + +From: Haotian Zhang + +[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ] + +In sy7636a_sensor_probe(), regulator_enable() is called but if +devm_hwmon_device_register_with_info() fails, the function returns +without calling regulator_disable(), leaving the regulator enabled +and leaking the reference count. + +Switch to devm_regulator_get_enable() to automatically +manage the regulator resource. + +Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sy7636a-hwmon.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c +index a12fc0ce70e76..d51daaf63d632 100644 +--- a/drivers/hwmon/sy7636a-hwmon.c ++++ b/drivers/hwmon/sy7636a-hwmon.c +@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { + static int sy7636a_sensor_probe(struct platform_device *pdev) + { + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); +- struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + +- regulator = devm_regulator_get(&pdev->dev, "vcom"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); ++ err = devm_regulator_get_enable(&pdev->dev, "vcom"); + if (err) + return err; + +-- +2.51.0 + diff --git a/queue-6.18/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-6.18/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..ead0e1e01a --- /dev/null +++ b/queue-6.18/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From 64cc97834f0c0c76d38dbd1a144195bd496f9a20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index d946db75df706..66513a27e6e77 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2883,10 +2883,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2894,6 +2890,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.18/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-6.18/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..850df254c7 --- /dev/null +++ b/queue-6.18/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From 02ef4601f565f161b81aeea70fbff616955e08df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index 9641e66a4e5f2..e70a64f2a32fa 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -406,21 +406,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-6.18/iavf-implement-settime64-with-eopnotsupp.patch b/queue-6.18/iavf-implement-settime64-with-eopnotsupp.patch new file mode 100644 index 0000000000..7b9e0cee47 --- /dev/null +++ b/queue-6.18/iavf-implement-settime64-with-eopnotsupp.patch @@ -0,0 +1,54 @@ +From b61b9cd9bc115efff4ed05028f5da811717b9eb2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:48:49 +0100 +Subject: iavf: Implement settime64 with -EOPNOTSUPP + +From: Michal Schmidt + +[ Upstream commit 1e43ebcd5152b3e681a334cc6542fb21770c3a2e ] + +ptp_clock_settime() assumes every ptp_clock has implemented settime64(). +Stub it with -EOPNOTSUPP to prevent a NULL dereference. + +The fix is similar to commit 329d050bbe63 ("gve: Implement settime64 +with -EOPNOTSUPP"). + +Fixes: d734223b2f0d ("iavf: add initial framework for registering PTP clock") +Signed-off-by: Michal Schmidt +Reviewed-by: Aleksandr Loktionov +Reviewed-by: Tim Hostetler +Link: https://patch.msgid.link/20251126094850.2842557-1-mschmidt@redhat.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/iavf/iavf_ptp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/net/ethernet/intel/iavf/iavf_ptp.c b/drivers/net/ethernet/intel/iavf/iavf_ptp.c +index b4d5eda2e84fc..9cbd8c1540318 100644 +--- a/drivers/net/ethernet/intel/iavf/iavf_ptp.c ++++ b/drivers/net/ethernet/intel/iavf/iavf_ptp.c +@@ -252,6 +252,12 @@ static int iavf_ptp_gettimex64(struct ptp_clock_info *info, + return iavf_read_phc_indirect(adapter, ts, sts); + } + ++static int iavf_ptp_settime64(struct ptp_clock_info *info, ++ const struct timespec64 *ts) ++{ ++ return -EOPNOTSUPP; ++} ++ + /** + * iavf_ptp_cache_phc_time - Cache PHC time for performing timestamp extension + * @adapter: private adapter structure +@@ -320,6 +326,7 @@ static int iavf_ptp_register_clock(struct iavf_adapter *adapter) + KBUILD_MODNAME, dev_name(dev)); + ptp_info->owner = THIS_MODULE; + ptp_info->gettimex64 = iavf_ptp_gettimex64; ++ ptp_info->settime64 = iavf_ptp_settime64; + ptp_info->do_aux_work = iavf_ptp_do_aux_work; + + clock = ptp_clock_register(ptp_info, dev); +-- +2.51.0 + diff --git a/queue-6.18/ice-extract-ice_init_dev-from-ice_init.patch b/queue-6.18/ice-extract-ice_init_dev-from-ice_init.patch new file mode 100644 index 0000000000..03a589e2e8 --- /dev/null +++ b/queue-6.18/ice-extract-ice_init_dev-from-ice_init.patch @@ -0,0 +1,96 @@ +From d1b82bb42a4342594e414cdb161020aba37b44ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:25 +0200 +Subject: ice: extract ice_init_dev() from ice_init() + +From: Przemek Kitszel + +[ Upstream commit c2fb9398f73d41cb2b5da74ff505578525ee3fd8 ] + +Extract ice_init_dev() from ice_init(), to allow service task and IRQ +scheme teardown to be put after clearing SW constructs in the subsequent +commit. + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 6b3d941f419b3..a12dcc733e041 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -5023,14 +5023,10 @@ static int ice_init(struct ice_pf *pf) + struct device *dev = ice_pf_to_dev(pf); + int err; + +- err = ice_init_dev(pf); +- if (err) +- return err; +- + err = ice_init_pf(pf); + if (err) { + dev_err(dev, "ice_init_pf failed: %d\n", err); +- goto unroll_dev_init; ++ return err; + } + + if (pf->hw.mac_type == ICE_MAC_E830) { +@@ -5080,8 +5076,6 @@ static int ice_init(struct ice_pf *pf) + ice_dealloc_vsis(pf); + unroll_pf_init: + ice_deinit_pf(pf); +-unroll_dev_init: +- ice_deinit_dev(pf); + return err; + } + +@@ -5093,7 +5087,6 @@ static void ice_deinit(struct ice_pf *pf) + ice_deinit_pf_sw(pf); + ice_dealloc_vsis(pf); + ice_deinit_pf(pf); +- ice_deinit_dev(pf); + } + + /** +@@ -5323,10 +5316,14 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + } + pf->adapter = adapter; + +- err = ice_init(pf); ++ err = ice_init_dev(pf); + if (err) + goto unroll_adapter; + ++ err = ice_init(pf); ++ if (err) ++ goto unroll_dev_init; ++ + devl_lock(priv_to_devlink(pf)); + err = ice_load(pf); + if (err) +@@ -5344,6 +5341,8 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + unroll_init: + devl_unlock(priv_to_devlink(pf)); + ice_deinit(pf); ++unroll_dev_init: ++ ice_deinit_dev(pf); + unroll_adapter: + ice_adapter_put(pdev); + unroll_hw_init: +@@ -5457,6 +5456,7 @@ static void ice_remove(struct pci_dev *pdev) + devl_unlock(priv_to_devlink(pf)); + + ice_deinit(pf); ++ ice_deinit_dev(pf); + ice_vsi_release_all(pf); + + ice_setup_mc_magic_wake(pf); +-- +2.51.0 + diff --git a/queue-6.18/ice-ice_init_pf-destroy-mutexes-and-xarrays-on-memor.patch b/queue-6.18/ice-ice_init_pf-destroy-mutexes-and-xarrays-on-memor.patch new file mode 100644 index 0000000000..2fbb01012d --- /dev/null +++ b/queue-6.18/ice-ice_init_pf-destroy-mutexes-and-xarrays-on-memor.patch @@ -0,0 +1,82 @@ +From c0aeef6b568376314cc341879353b33b3c1ecc0f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:22 +0200 +Subject: ice: ice_init_pf: destroy mutexes and xarrays on memory alloc failure + +From: Przemek Kitszel + +[ Upstream commit 71430451f81bd6550e46d89b69103a111fc42982 ] + +Unroll actions of ice_init_pf() when it fails. +ice_deinit_pf() happens to be perfect to call here. + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 31 +++++++++-------------- + 1 file changed, 12 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 13db83fb383e6..80349aed1f9d6 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -3951,6 +3951,8 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf) + */ + static void ice_deinit_pf(struct ice_pf *pf) + { ++ /* note that we unroll also on ice_init_pf() failure here */ ++ + mutex_destroy(&pf->lag_mutex); + mutex_destroy(&pf->adev_mutex); + mutex_destroy(&pf->sw_mutex); +@@ -4055,25 +4057,6 @@ static int ice_init_pf(struct ice_pf *pf) + init_waitqueue_head(&pf->reset_wait_queue); + + mutex_init(&pf->avail_q_mutex); +- pf->avail_txqs = bitmap_zalloc(pf->max_pf_txqs, GFP_KERNEL); +- if (!pf->avail_txqs) +- return -ENOMEM; +- +- pf->avail_rxqs = bitmap_zalloc(pf->max_pf_rxqs, GFP_KERNEL); +- if (!pf->avail_rxqs) { +- bitmap_free(pf->avail_txqs); +- pf->avail_txqs = NULL; +- return -ENOMEM; +- } +- +- pf->txtime_txqs = bitmap_zalloc(pf->max_pf_txqs, GFP_KERNEL); +- if (!pf->txtime_txqs) { +- bitmap_free(pf->avail_txqs); +- pf->avail_txqs = NULL; +- bitmap_free(pf->avail_rxqs); +- pf->avail_rxqs = NULL; +- return -ENOMEM; +- } + + mutex_init(&pf->vfs.table_lock); + hash_init(pf->vfs.table); +@@ -4086,7 +4069,17 @@ static int ice_init_pf(struct ice_pf *pf) + xa_init(&pf->dyn_ports); + xa_init(&pf->sf_nums); + ++ pf->avail_txqs = bitmap_zalloc(pf->max_pf_txqs, GFP_KERNEL); ++ pf->avail_rxqs = bitmap_zalloc(pf->max_pf_rxqs, GFP_KERNEL); ++ pf->txtime_txqs = bitmap_zalloc(pf->max_pf_txqs, GFP_KERNEL); ++ if (!pf->avail_txqs || !pf->avail_rxqs || !pf->txtime_txqs) ++ goto undo_init; ++ + return 0; ++undo_init: ++ /* deinit handles half-initialized pf just fine */ ++ ice_deinit_pf(pf); ++ return -ENOMEM; + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/ice-move-ice_deinit_dev-to-the-end-of-deinit-paths.patch b/queue-6.18/ice-move-ice_deinit_dev-to-the-end-of-deinit-paths.patch new file mode 100644 index 0000000000..476fdc0e48 --- /dev/null +++ b/queue-6.18/ice-move-ice_deinit_dev-to-the-end-of-deinit-paths.patch @@ -0,0 +1,169 @@ +From edb69399762c9c6c3059248d7fb5efa6cf870560 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:26 +0200 +Subject: ice: move ice_deinit_dev() to the end of deinit paths + +From: Przemek Kitszel + +[ Upstream commit 8a37f9e2ff40f4a4fa8def22febefe4daf58e573 ] + +ice_deinit_dev() takes care of turning off adminq processing, which is +much needed during driver teardown (remove, reset, error path). Move it +to the very end where applicable. +For example, ice_deinit_hw() called after adminq deinit slows rmmod on +my two-card setup by about 60 seconds. + +ice_init_dev() and ice_deinit_dev() scopes were reduced by previous +commits of the series, with a final touch of extracting ice_init_dev_hw() +out now (there is no deinit counterpart). + +Note that removed ice_service_task_stop() call from ice_remove() is placed +in the ice_deinit_dev() (and stopping twice makes no sense). + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/intel/ice/devlink/devlink.c | 5 +++- + drivers/net/ethernet/intel/ice/ice.h | 1 + + drivers/net/ethernet/intel/ice/ice_common.c | 3 +++ + drivers/net/ethernet/intel/ice/ice_main.c | 23 ++++++++++++------- + 4 files changed, 23 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c +index c354a03c950cd..938914abbe066 100644 +--- a/drivers/net/ethernet/intel/ice/devlink/devlink.c ++++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c +@@ -1233,6 +1233,7 @@ static int ice_devlink_reinit_up(struct ice_pf *pf) + { + struct ice_vsi *vsi = ice_get_main_vsi(pf); + struct device *dev = ice_pf_to_dev(pf); ++ bool need_dev_deinit = false; + int err; + + err = ice_init_hw(&pf->hw); +@@ -1276,9 +1277,11 @@ static int ice_devlink_reinit_up(struct ice_pf *pf) + unroll_pf_init: + ice_deinit_pf(pf); + unroll_dev_init: +- ice_deinit_dev(pf); ++ need_dev_deinit = true; + unroll_hw_init: + ice_deinit_hw(&pf->hw); ++ if (need_dev_deinit) ++ ice_deinit_dev(pf); + return err; + } + +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index 9a1abd4573372..9ee596773f34e 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -1033,6 +1033,7 @@ void ice_start_service_task(struct ice_pf *pf); + int ice_load(struct ice_pf *pf); + void ice_unload(struct ice_pf *pf); + void ice_adv_lnk_speed_maps_init(void); ++void ice_init_dev_hw(struct ice_pf *pf); + int ice_init_dev(struct ice_pf *pf); + void ice_deinit_dev(struct ice_pf *pf); + int ice_init_pf(struct ice_pf *pf); +diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c +index 2532b6f82e971..6edeb06b4dce2 100644 +--- a/drivers/net/ethernet/intel/ice/ice_common.c ++++ b/drivers/net/ethernet/intel/ice/ice_common.c +@@ -1161,6 +1161,9 @@ int ice_init_hw(struct ice_hw *hw) + status = ice_init_hw_tbls(hw); + if (status) + goto err_unroll_fltr_mgmt_struct; ++ ++ ice_init_dev_hw(hw->back); ++ + mutex_init(&hw->tnl_lock); + ice_init_chk_recipe_reuse_support(hw); + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index a12dcc733e041..f1ebdb7dbdc73 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4742,9 +4742,8 @@ static void ice_decfg_netdev(struct ice_vsi *vsi) + vsi->netdev = NULL; + } + +-int ice_init_dev(struct ice_pf *pf) ++void ice_init_dev_hw(struct ice_pf *pf) + { +- struct device *dev = ice_pf_to_dev(pf); + struct ice_hw *hw = &pf->hw; + int err; + +@@ -4764,6 +4763,12 @@ int ice_init_dev(struct ice_pf *pf) + */ + ice_set_safe_mode_caps(hw); + } ++} ++ ++int ice_init_dev(struct ice_pf *pf) ++{ ++ struct device *dev = ice_pf_to_dev(pf); ++ int err; + + ice_set_pf_caps(pf); + err = ice_init_interrupt_scheme(pf); +@@ -5220,6 +5225,7 @@ static int + ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + { + struct device *dev = &pdev->dev; ++ bool need_dev_deinit = false; + struct ice_adapter *adapter; + struct ice_pf *pf; + struct ice_hw *hw; +@@ -5342,11 +5348,13 @@ ice_probe(struct pci_dev *pdev, const struct pci_device_id __always_unused *ent) + devl_unlock(priv_to_devlink(pf)); + ice_deinit(pf); + unroll_dev_init: +- ice_deinit_dev(pf); ++ need_dev_deinit = true; + unroll_adapter: + ice_adapter_put(pdev); + unroll_hw_init: + ice_deinit_hw(hw); ++ if (need_dev_deinit) ++ ice_deinit_dev(pf); + return err; + } + +@@ -5441,10 +5449,6 @@ static void ice_remove(struct pci_dev *pdev) + + ice_hwmon_exit(pf); + +- ice_service_task_stop(pf); +- ice_aq_cancel_waiting_tasks(pf); +- set_bit(ICE_DOWN, pf->state); +- + if (!ice_is_safe_mode(pf)) + ice_remove_arfs(pf); + +@@ -5456,13 +5460,16 @@ static void ice_remove(struct pci_dev *pdev) + devl_unlock(priv_to_devlink(pf)); + + ice_deinit(pf); +- ice_deinit_dev(pf); + ice_vsi_release_all(pf); + + ice_setup_mc_magic_wake(pf); + ice_set_wake(pf); + + ice_adapter_put(pdev); ++ ++ ice_deinit_dev(pf); ++ ice_aq_cancel_waiting_tasks(pf); ++ set_bit(ICE_DOWN, pf->state); + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/ice-move-ice_init_interrupt_scheme-prior-ice_init_pf.patch b/queue-6.18/ice-move-ice_init_interrupt_scheme-prior-ice_init_pf.patch new file mode 100644 index 0000000000..aea2190f7c --- /dev/null +++ b/queue-6.18/ice-move-ice_init_interrupt_scheme-prior-ice_init_pf.patch @@ -0,0 +1,101 @@ +From 1a60dabfd7828863aa2948b395d525a675cd87e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:21 +0200 +Subject: ice: move ice_init_interrupt_scheme() prior ice_init_pf() + +From: Przemek Kitszel + +[ Upstream commit 2fe18288fce6b421f1dc585bcb9dd3afa32d3ad9 ] + +Move ice_init_interrupt_scheme() prior ice_init_pf(). +To enable the move ice_set_pf_caps() was moved out from ice_init_pf() +to the caller (ice_init_dev()), and placed prior to the irq scheme init. + +The move makes deinit order of ice_deinit_dev() and failure-path of +ice_init_pf() match (at least in terms of not calling +ice_clear_interrupt_scheme() and ice_deinit_pf() in opposite ways). + +The new order aligns with findings made by Jakub Buchocki in +the commit 24b454bc354a ("ice: Fix ice module unload"). + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 25 ++++++++++------------- + 1 file changed, 11 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 41c2f0d52ce0d..13db83fb383e6 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4043,8 +4043,6 @@ void ice_start_service_task(struct ice_pf *pf) + */ + static int ice_init_pf(struct ice_pf *pf) + { +- ice_set_pf_caps(pf); +- + mutex_init(&pf->sw_mutex); + mutex_init(&pf->tc_mutex); + mutex_init(&pf->adev_mutex); +@@ -4746,11 +4744,18 @@ int ice_init_dev(struct ice_pf *pf) + ice_set_safe_mode_caps(hw); + } + ++ ice_set_pf_caps(pf); ++ err = ice_init_interrupt_scheme(pf); ++ if (err) { ++ dev_err(dev, "ice_init_interrupt_scheme failed: %d\n", err); ++ return -EIO; ++ } ++ + ice_start_service_task(pf); + err = ice_init_pf(pf); + if (err) { + dev_err(dev, "ice_init_pf failed: %d\n", err); +- return err; ++ goto unroll_irq_scheme_init; + } + + pf->hw.udp_tunnel_nic.set_port = ice_udp_tunnel_set_port; +@@ -4768,14 +4773,6 @@ int ice_init_dev(struct ice_pf *pf) + pf->hw.udp_tunnel_nic.tables[1].tunnel_types = + UDP_TUNNEL_TYPE_GENEVE; + } +- +- err = ice_init_interrupt_scheme(pf); +- if (err) { +- dev_err(dev, "ice_init_interrupt_scheme failed: %d\n", err); +- err = -EIO; +- goto unroll_pf_init; +- } +- + /* In case of MSIX we are going to setup the misc vector right here + * to handle admin queue events etc. In case of legacy and MSI + * the misc functionality and queue processing is combined in +@@ -4784,16 +4781,16 @@ int ice_init_dev(struct ice_pf *pf) + err = ice_req_irq_msix_misc(pf); + if (err) { + dev_err(dev, "setup of misc vector failed: %d\n", err); +- goto unroll_irq_scheme_init; ++ goto unroll_pf_init; + } + + return 0; + +-unroll_irq_scheme_init: +- ice_clear_interrupt_scheme(pf); + unroll_pf_init: + ice_deinit_pf(pf); ++unroll_irq_scheme_init: + ice_service_task_stop(pf); ++ ice_clear_interrupt_scheme(pf); + return err; + } + +-- +2.51.0 + diff --git a/queue-6.18/ice-move-ice_init_pf-out-of-ice_init_dev.patch b/queue-6.18/ice-move-ice_init_pf-out-of-ice_init_dev.patch new file mode 100644 index 0000000000..e40d4d255b --- /dev/null +++ b/queue-6.18/ice-move-ice_init_pf-out-of-ice_init_dev.patch @@ -0,0 +1,196 @@ +From a09658d08668df64ff62a71f89e450359d625191 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:24 +0200 +Subject: ice: move ice_init_pf() out of ice_init_dev() + +From: Przemek Kitszel + +[ Upstream commit ef825bdb4605742c4efc03f67d930e80c42f33cb ] + +Move ice_init_pf() out of ice_init_dev(). +Do the same for deinit counterpart. + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + .../net/ethernet/intel/ice/devlink/devlink.c | 16 ++++++++-- + drivers/net/ethernet/intel/ice/ice.h | 2 ++ + drivers/net/ethernet/intel/ice/ice_main.c | 32 +++++++++---------- + 3 files changed, 31 insertions(+), 19 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/devlink/devlink.c b/drivers/net/ethernet/intel/ice/devlink/devlink.c +index fb2de521731ae..c354a03c950cd 100644 +--- a/drivers/net/ethernet/intel/ice/devlink/devlink.c ++++ b/drivers/net/ethernet/intel/ice/devlink/devlink.c +@@ -459,6 +459,7 @@ static void ice_devlink_reinit_down(struct ice_pf *pf) + rtnl_lock(); + ice_vsi_decfg(ice_get_main_vsi(pf)); + rtnl_unlock(); ++ ice_deinit_pf(pf); + ice_deinit_dev(pf); + } + +@@ -1231,11 +1232,12 @@ static void ice_set_min_max_msix(struct ice_pf *pf) + static int ice_devlink_reinit_up(struct ice_pf *pf) + { + struct ice_vsi *vsi = ice_get_main_vsi(pf); ++ struct device *dev = ice_pf_to_dev(pf); + int err; + + err = ice_init_hw(&pf->hw); + if (err) { +- dev_err(ice_pf_to_dev(pf), "ice_init_hw failed: %d\n", err); ++ dev_err(dev, "ice_init_hw failed: %d\n", err); + return err; + } + +@@ -1246,13 +1248,19 @@ static int ice_devlink_reinit_up(struct ice_pf *pf) + if (err) + goto unroll_hw_init; + ++ err = ice_init_pf(pf); ++ if (err) { ++ dev_err(dev, "ice_init_pf failed: %d\n", err); ++ goto unroll_dev_init; ++ } ++ + vsi->flags = ICE_VSI_FLAG_INIT; + + rtnl_lock(); + err = ice_vsi_cfg(vsi); + rtnl_unlock(); + if (err) +- goto err_vsi_cfg; ++ goto unroll_pf_init; + + /* No need to take devl_lock, it's already taken by devlink API */ + err = ice_load(pf); +@@ -1265,7 +1273,9 @@ static int ice_devlink_reinit_up(struct ice_pf *pf) + rtnl_lock(); + ice_vsi_decfg(vsi); + rtnl_unlock(); +-err_vsi_cfg: ++unroll_pf_init: ++ ice_deinit_pf(pf); ++unroll_dev_init: + ice_deinit_dev(pf); + unroll_hw_init: + ice_deinit_hw(&pf->hw); +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index 0e58a58c23eb3..9a1abd4573372 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -1035,6 +1035,8 @@ void ice_unload(struct ice_pf *pf); + void ice_adv_lnk_speed_maps_init(void); + int ice_init_dev(struct ice_pf *pf); + void ice_deinit_dev(struct ice_pf *pf); ++int ice_init_pf(struct ice_pf *pf); ++void ice_deinit_pf(struct ice_pf *pf); + int ice_change_mtu(struct net_device *netdev, int new_mtu); + void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue); + int ice_xdp(struct net_device *dev, struct netdev_bpf *xdp); +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 6773b918daffc..6b3d941f419b3 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -3949,7 +3949,7 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf) + * ice_deinit_pf - Unrolls initialziations done by ice_init_pf + * @pf: board private structure to initialize + */ +-static void ice_deinit_pf(struct ice_pf *pf) ++void ice_deinit_pf(struct ice_pf *pf) + { + /* note that we unroll also on ice_init_pf() failure here */ + +@@ -4045,8 +4045,9 @@ void ice_start_service_task(struct ice_pf *pf) + /** + * ice_init_pf - Initialize general software structures (struct ice_pf) + * @pf: board private structure to initialize ++ * Return: 0 on success, negative errno otherwise. + */ +-static int ice_init_pf(struct ice_pf *pf) ++int ice_init_pf(struct ice_pf *pf) + { + struct udp_tunnel_nic_info *udp_tunnel_nic = &pf->hw.udp_tunnel_nic; + struct device *dev = ice_pf_to_dev(pf); +@@ -4772,23 +4773,12 @@ int ice_init_dev(struct ice_pf *pf) + } + + ice_start_service_task(pf); +- err = ice_init_pf(pf); +- if (err) { +- dev_err(dev, "ice_init_pf failed: %d\n", err); +- goto unroll_irq_scheme_init; +- } + + return 0; +- +-unroll_irq_scheme_init: +- ice_service_task_stop(pf); +- ice_clear_interrupt_scheme(pf); +- return err; + } + + void ice_deinit_dev(struct ice_pf *pf) + { +- ice_deinit_pf(pf); + ice_deinit_hw(&pf->hw); + ice_service_task_stop(pf); + +@@ -5030,21 +5020,28 @@ static void ice_deinit_devlink(struct ice_pf *pf) + + static int ice_init(struct ice_pf *pf) + { ++ struct device *dev = ice_pf_to_dev(pf); + int err; + + err = ice_init_dev(pf); + if (err) + return err; + ++ err = ice_init_pf(pf); ++ if (err) { ++ dev_err(dev, "ice_init_pf failed: %d\n", err); ++ goto unroll_dev_init; ++ } ++ + if (pf->hw.mac_type == ICE_MAC_E830) { + err = pci_enable_ptm(pf->pdev, NULL); + if (err) +- dev_dbg(ice_pf_to_dev(pf), "PCIe PTM not supported by PCIe bus/controller\n"); ++ dev_dbg(dev, "PCIe PTM not supported by PCIe bus/controller\n"); + } + + err = ice_alloc_vsis(pf); + if (err) +- goto err_alloc_vsis; ++ goto unroll_pf_init; + + err = ice_init_pf_sw(pf); + if (err) +@@ -5081,7 +5078,9 @@ static int ice_init(struct ice_pf *pf) + ice_deinit_pf_sw(pf); + err_init_pf_sw: + ice_dealloc_vsis(pf); +-err_alloc_vsis: ++unroll_pf_init: ++ ice_deinit_pf(pf); ++unroll_dev_init: + ice_deinit_dev(pf); + return err; + } +@@ -5093,6 +5092,7 @@ static void ice_deinit(struct ice_pf *pf) + + ice_deinit_pf_sw(pf); + ice_dealloc_vsis(pf); ++ ice_deinit_pf(pf); + ice_deinit_dev(pf); + } + +-- +2.51.0 + diff --git a/queue-6.18/ice-move-service-task-start-out-of-ice_init_pf.patch b/queue-6.18/ice-move-service-task-start-out-of-ice_init_pf.patch new file mode 100644 index 0000000000..c152e6452d --- /dev/null +++ b/queue-6.18/ice-move-service-task-start-out-of-ice_init_pf.patch @@ -0,0 +1,102 @@ +From f95b202c5e6137be92e462dadb9fb0ac1bf44b28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:20 +0200 +Subject: ice: move service task start out of ice_init_pf() + +From: Przemek Kitszel + +[ Upstream commit 806c4f32a80627f8977fda53520afc41491d162f ] + +Move service task start out of ice_init_pf(). Do analogous with deinit. +Service task is needed up to the very end of driver removal, later commit +of the series will move it later on execution timeline. + +Signed-off-by: Przemek Kitszel +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice.h | 1 + + drivers/net/ethernet/intel/ice/ice_main.c | 18 +++++++++++------- + 2 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice.h b/drivers/net/ethernet/intel/ice/ice.h +index 22b8323ff0d0e..0e58a58c23eb3 100644 +--- a/drivers/net/ethernet/intel/ice/ice.h ++++ b/drivers/net/ethernet/intel/ice/ice.h +@@ -1029,6 +1029,7 @@ int ice_open(struct net_device *netdev); + int ice_open_internal(struct net_device *netdev); + int ice_stop(struct net_device *netdev); + void ice_service_task_schedule(struct ice_pf *pf); ++void ice_start_service_task(struct ice_pf *pf); + int ice_load(struct ice_pf *pf); + void ice_unload(struct ice_pf *pf); + void ice_adv_lnk_speed_maps_init(void); +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 86f5859e88ef5..41c2f0d52ce0d 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -3951,7 +3951,6 @@ u16 ice_get_avail_rxq_count(struct ice_pf *pf) + */ + static void ice_deinit_pf(struct ice_pf *pf) + { +- ice_service_task_stop(pf); + mutex_destroy(&pf->lag_mutex); + mutex_destroy(&pf->adev_mutex); + mutex_destroy(&pf->sw_mutex); +@@ -4030,6 +4029,14 @@ static void ice_set_pf_caps(struct ice_pf *pf) + pf->max_pf_rxqs = func_caps->common_cap.num_rxq; + } + ++void ice_start_service_task(struct ice_pf *pf) ++{ ++ timer_setup(&pf->serv_tmr, ice_service_timer, 0); ++ pf->serv_tmr_period = HZ; ++ INIT_WORK(&pf->serv_task, ice_service_task); ++ clear_bit(ICE_SERVICE_SCHED, pf->state); ++} ++ + /** + * ice_init_pf - Initialize general software structures (struct ice_pf) + * @pf: board private structure to initialize +@@ -4049,12 +4056,6 @@ static int ice_init_pf(struct ice_pf *pf) + + init_waitqueue_head(&pf->reset_wait_queue); + +- /* setup service timer and periodic service task */ +- timer_setup(&pf->serv_tmr, ice_service_timer, 0); +- pf->serv_tmr_period = HZ; +- INIT_WORK(&pf->serv_task, ice_service_task); +- clear_bit(ICE_SERVICE_SCHED, pf->state); +- + mutex_init(&pf->avail_q_mutex); + pf->avail_txqs = bitmap_zalloc(pf->max_pf_txqs, GFP_KERNEL); + if (!pf->avail_txqs) +@@ -4745,6 +4746,7 @@ int ice_init_dev(struct ice_pf *pf) + ice_set_safe_mode_caps(hw); + } + ++ ice_start_service_task(pf); + err = ice_init_pf(pf); + if (err) { + dev_err(dev, "ice_init_pf failed: %d\n", err); +@@ -4791,6 +4793,7 @@ int ice_init_dev(struct ice_pf *pf) + ice_clear_interrupt_scheme(pf); + unroll_pf_init: + ice_deinit_pf(pf); ++ ice_service_task_stop(pf); + return err; + } + +@@ -4799,6 +4802,7 @@ void ice_deinit_dev(struct ice_pf *pf) + ice_free_irq_msix_misc(pf); + ice_deinit_pf(pf); + ice_deinit_hw(&pf->hw); ++ ice_service_task_stop(pf); + + /* Service task is already stopped, so call reset directly. */ + ice_reset(&pf->hw, ICE_RESET_PFR); +-- +2.51.0 + diff --git a/queue-6.18/ice-move-udp_tunnel_nic-and-misc-irq-setup-into-ice_.patch b/queue-6.18/ice-move-udp_tunnel_nic-and-misc-irq-setup-into-ice_.patch new file mode 100644 index 0000000000..0d50ff7fb8 --- /dev/null +++ b/queue-6.18/ice-move-udp_tunnel_nic-and-misc-irq-setup-into-ice_.patch @@ -0,0 +1,132 @@ +From e1a0f4fce53848dd0a36efd72c5f9bd9750f704d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:23 +0200 +Subject: ice: move udp_tunnel_nic and misc IRQ setup into ice_init_pf() + +From: Przemek Kitszel + +[ Upstream commit e3bf1cdde7471bab7fc20dd1a37c2cdb82d3f76b ] + +Move udp_tunnel_nic setup and ice_req_irq_msix_misc() call into +ice_init_pf(), remove some redundancy in the former while moving. + +Move ice_free_irq_msix_misc() call into ice_deinit_pf(), to mimic +the above in terms of needed cleanup. Guard it via emptiness check, +to keep the allowance of half-initialized pf being cleaned up. + +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Stable-dep-of: 1390b8b3d2be ("ice: remove duplicate call to ice_deinit_hw() on error paths") +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 58 +++++++++++------------ + 1 file changed, 28 insertions(+), 30 deletions(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index 80349aed1f9d6..6773b918daffc 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -3978,6 +3978,9 @@ static void ice_deinit_pf(struct ice_pf *pf) + if (pf->ptp.clock) + ptp_clock_unregister(pf->ptp.clock); + ++ if (!xa_empty(&pf->irq_tracker.entries)) ++ ice_free_irq_msix_misc(pf); ++ + xa_destroy(&pf->dyn_ports); + xa_destroy(&pf->sf_nums); + } +@@ -4045,6 +4048,11 @@ void ice_start_service_task(struct ice_pf *pf) + */ + static int ice_init_pf(struct ice_pf *pf) + { ++ struct udp_tunnel_nic_info *udp_tunnel_nic = &pf->hw.udp_tunnel_nic; ++ struct device *dev = ice_pf_to_dev(pf); ++ struct ice_hw *hw = &pf->hw; ++ int err = -ENOMEM; ++ + mutex_init(&pf->sw_mutex); + mutex_init(&pf->tc_mutex); + mutex_init(&pf->adev_mutex); +@@ -4075,11 +4083,30 @@ static int ice_init_pf(struct ice_pf *pf) + if (!pf->avail_txqs || !pf->avail_rxqs || !pf->txtime_txqs) + goto undo_init; + ++ udp_tunnel_nic->set_port = ice_udp_tunnel_set_port; ++ udp_tunnel_nic->unset_port = ice_udp_tunnel_unset_port; ++ udp_tunnel_nic->shared = &hw->udp_tunnel_shared; ++ udp_tunnel_nic->tables[0].n_entries = hw->tnl.valid_count[TNL_VXLAN]; ++ udp_tunnel_nic->tables[0].tunnel_types = UDP_TUNNEL_TYPE_VXLAN; ++ udp_tunnel_nic->tables[1].n_entries = hw->tnl.valid_count[TNL_GENEVE]; ++ udp_tunnel_nic->tables[1].tunnel_types = UDP_TUNNEL_TYPE_GENEVE; ++ ++ /* In case of MSIX we are going to setup the misc vector right here ++ * to handle admin queue events etc. In case of legacy and MSI ++ * the misc functionality and queue processing is combined in ++ * the same vector and that gets setup at open. ++ */ ++ err = ice_req_irq_msix_misc(pf); ++ if (err) { ++ dev_err(dev, "setup of misc vector failed: %d\n", err); ++ goto undo_init; ++ } ++ + return 0; + undo_init: + /* deinit handles half-initialized pf just fine */ + ice_deinit_pf(pf); +- return -ENOMEM; ++ return err; + } + + /** +@@ -4751,36 +4778,8 @@ int ice_init_dev(struct ice_pf *pf) + goto unroll_irq_scheme_init; + } + +- pf->hw.udp_tunnel_nic.set_port = ice_udp_tunnel_set_port; +- pf->hw.udp_tunnel_nic.unset_port = ice_udp_tunnel_unset_port; +- pf->hw.udp_tunnel_nic.shared = &pf->hw.udp_tunnel_shared; +- if (pf->hw.tnl.valid_count[TNL_VXLAN]) { +- pf->hw.udp_tunnel_nic.tables[0].n_entries = +- pf->hw.tnl.valid_count[TNL_VXLAN]; +- pf->hw.udp_tunnel_nic.tables[0].tunnel_types = +- UDP_TUNNEL_TYPE_VXLAN; +- } +- if (pf->hw.tnl.valid_count[TNL_GENEVE]) { +- pf->hw.udp_tunnel_nic.tables[1].n_entries = +- pf->hw.tnl.valid_count[TNL_GENEVE]; +- pf->hw.udp_tunnel_nic.tables[1].tunnel_types = +- UDP_TUNNEL_TYPE_GENEVE; +- } +- /* In case of MSIX we are going to setup the misc vector right here +- * to handle admin queue events etc. In case of legacy and MSI +- * the misc functionality and queue processing is combined in +- * the same vector and that gets setup at open. +- */ +- err = ice_req_irq_msix_misc(pf); +- if (err) { +- dev_err(dev, "setup of misc vector failed: %d\n", err); +- goto unroll_pf_init; +- } +- + return 0; + +-unroll_pf_init: +- ice_deinit_pf(pf); + unroll_irq_scheme_init: + ice_service_task_stop(pf); + ice_clear_interrupt_scheme(pf); +@@ -4789,7 +4788,6 @@ int ice_init_dev(struct ice_pf *pf) + + void ice_deinit_dev(struct ice_pf *pf) + { +- ice_free_irq_msix_misc(pf); + ice_deinit_pf(pf); + ice_deinit_hw(&pf->hw); + ice_service_task_stop(pf); +-- +2.51.0 + diff --git a/queue-6.18/ice-remove-duplicate-call-to-ice_deinit_hw-on-error-.patch b/queue-6.18/ice-remove-duplicate-call-to-ice_deinit_hw-on-error-.patch new file mode 100644 index 0000000000..8d82eab701 --- /dev/null +++ b/queue-6.18/ice-remove-duplicate-call-to-ice_deinit_hw-on-error-.patch @@ -0,0 +1,52 @@ +From 35b35436505c377456c5edadb4187aeb73e8064e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 15:06:27 +0200 +Subject: ice: remove duplicate call to ice_deinit_hw() on error paths + +From: Przemek Kitszel + +[ Upstream commit 1390b8b3d2bef9bfbb852fc735430798bfca36e7 ] + +Current unwinding code on error paths of ice_devlink_reinit_up() and +ice_probe() have manual call to ice_deinit_hw() (which is good, as there +is also manual call to ice_hw_init() there), which is then duplicated +(and was prior current series) in ice_deinit_dev(). + +Fix the above by removing ice_deinit_hw() from ice_deinit_dev(). +Add a (now missing) call in ice_remove(). + +Reported-by: Jacob Keller +Link: https://lore.kernel.org/intel-wired-lan/20250717-jk-ddp-safe-mode-issue-v1-1-e113b2baed79@intel.com/ +Fixes: 4d3f59bfa2cd ("ice: split ice_init_hw() out from ice_init_dev()") +Signed-off-by: Przemek Kitszel +Reviewed-by: Aleksandr Loktionov +Tested-by: Rinitha S (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/ice/ice_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c +index f1ebdb7dbdc73..b0f8a96c13b47 100644 +--- a/drivers/net/ethernet/intel/ice/ice_main.c ++++ b/drivers/net/ethernet/intel/ice/ice_main.c +@@ -4784,7 +4784,6 @@ int ice_init_dev(struct ice_pf *pf) + + void ice_deinit_dev(struct ice_pf *pf) + { +- ice_deinit_hw(&pf->hw); + ice_service_task_stop(pf); + + /* Service task is already stopped, so call reset directly. */ +@@ -5466,6 +5465,7 @@ static void ice_remove(struct pci_dev *pdev) + ice_set_wake(pf); + + ice_adapter_put(pdev); ++ ice_deinit_hw(&pf->hw); + + ice_deinit_dev(pf); + ice_aq_cancel_waiting_tasks(pf); +-- +2.51.0 + diff --git a/queue-6.18/iio-core-add-missing-mutex_destroy-in-iio_dev_releas.patch b/queue-6.18/iio-core-add-missing-mutex_destroy-in-iio_dev_releas.patch new file mode 100644 index 0000000000..5215cf7b6d --- /dev/null +++ b/queue-6.18/iio-core-add-missing-mutex_destroy-in-iio_dev_releas.patch @@ -0,0 +1,68 @@ +From 00ed0fe1b785a4f02e3e3987646f67518bf786cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:55:08 +0100 +Subject: iio: core: add missing mutex_destroy in iio_dev_release() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Shevchenko + +[ Upstream commit f5d203467a31798191365efeb16cd619d2c8f23a ] + +Add missing mutex_destroy() call in iio_dev_release() to properly +clean up the mutex initialized in iio_device_alloc(). Ensure proper +resource cleanup and follows kernel practices. + +Found by code review. + +While at it, create a lockdep key before mutex initialisation. +This will help with converting it to the better API in the future. + +Fixes: 847ec80bbaa7 ("Staging: IIO: core support for device registration and management") +Fixes: ac917a81117c ("staging:iio:core set the iio_dev.info pointer to null on unregister under lock.") +Signed-off-by: Andy Shevchenko +Reviewed-by: Nuno Sá +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/industrialio-core.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index 88c3d585a1bd0..93d6e5b101cf1 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -1654,6 +1654,9 @@ static void iio_dev_release(struct device *device) + + iio_device_detach_buffers(indio_dev); + ++ mutex_destroy(&iio_dev_opaque->info_exist_lock); ++ mutex_destroy(&iio_dev_opaque->mlock); ++ + lockdep_unregister_key(&iio_dev_opaque->mlock_key); + + ida_free(&iio_ida, iio_dev_opaque->id); +@@ -1698,8 +1701,7 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) + indio_dev->dev.type = &iio_device_type; + indio_dev->dev.bus = &iio_bus_type; + device_initialize(&indio_dev->dev); +- mutex_init(&iio_dev_opaque->mlock); +- mutex_init(&iio_dev_opaque->info_exist_lock); ++ + INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); + + iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL); +@@ -1722,6 +1724,9 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) + lockdep_register_key(&iio_dev_opaque->mlock_key); + lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); + ++ mutex_init(&iio_dev_opaque->mlock); ++ mutex_init(&iio_dev_opaque->info_exist_lock); ++ + return indio_dev; + } + EXPORT_SYMBOL(iio_device_alloc); +-- +2.51.0 + diff --git a/queue-6.18/iio-core-clean-up-device-correctly-on-iio_device_all.patch b/queue-6.18/iio-core-clean-up-device-correctly-on-iio_device_all.patch new file mode 100644 index 0000000000..c9fcbc08ee --- /dev/null +++ b/queue-6.18/iio-core-clean-up-device-correctly-on-iio_device_all.patch @@ -0,0 +1,56 @@ +From 1b610a564ed71927abe25e645ce3cc0b32925216 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:55:09 +0100 +Subject: iio: core: Clean up device correctly on iio_device_alloc() failure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Andy Shevchenko + +[ Upstream commit b0e6871415b25f5e84a79621834e3d0c9d4627a6 ] + +Once we called device_initialize() we have to call put_device() +on it. Refactor the code to make it in the right order. + +Fixes: fe6f45f6ba22 ("iio: core: check return value when calling dev_set_name()") +Fixes: 847ec80bbaa7 ("Staging: IIO: core support for device registration and management") +Signed-off-by: Andy Shevchenko +Reviewed-by: Nuno Sá +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/industrialio-core.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/iio/industrialio-core.c b/drivers/iio/industrialio-core.c +index 93d6e5b101cf1..5d2f35cf18bc3 100644 +--- a/drivers/iio/industrialio-core.c ++++ b/drivers/iio/industrialio-core.c +@@ -1697,11 +1697,6 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) + ACCESS_PRIVATE(indio_dev, priv) = (char *)iio_dev_opaque + + ALIGN(sizeof(*iio_dev_opaque), IIO_DMA_MINALIGN); + +- indio_dev->dev.parent = parent; +- indio_dev->dev.type = &iio_device_type; +- indio_dev->dev.bus = &iio_bus_type; +- device_initialize(&indio_dev->dev); +- + INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); + + iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL); +@@ -1727,6 +1722,11 @@ struct iio_dev *iio_device_alloc(struct device *parent, int sizeof_priv) + mutex_init(&iio_dev_opaque->mlock); + mutex_init(&iio_dev_opaque->info_exist_lock); + ++ indio_dev->dev.parent = parent; ++ indio_dev->dev.type = &iio_device_type; ++ indio_dev->dev.bus = &iio_bus_type; ++ device_initialize(&indio_dev->dev); ++ + return indio_dev; + } + EXPORT_SYMBOL(iio_device_alloc); +-- +2.51.0 + diff --git a/queue-6.18/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch b/queue-6.18/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch new file mode 100644 index 0000000000..0ac165b616 --- /dev/null +++ b/queue-6.18/iio-imu-bmi270-fix-dev_err_probe-error-msg.patch @@ -0,0 +1,38 @@ +From 1588bd9ac2ab61b9cf9a3b4939e44627bd9eb4e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 19:30:18 -0300 +Subject: iio: imu: bmi270: fix dev_err_probe error msg + +From: Rodrigo Gobbi + +[ Upstream commit 02f86101e430cce9a99a044b483c4ed5b91bb3b8 ] + +The bmi270 can be connected to I2C or a SPI interface. If it is a SPI, +during probe, if devm_regmap_init() fails, it should print the "spi" +term rather "i2c". + +Fixes: 92cc50a00574 ("iio: imu: bmi270: Add spi driver for bmi270 imu") +Signed-off-by: Rodrigo Gobbi +Reviewed-by: Andy Shevchenko +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/bmi270/bmi270_spi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/bmi270/bmi270_spi.c b/drivers/iio/imu/bmi270/bmi270_spi.c +index 19dd7734f9d07..80c9fa1d685ab 100644 +--- a/drivers/iio/imu/bmi270/bmi270_spi.c ++++ b/drivers/iio/imu/bmi270/bmi270_spi.c +@@ -60,7 +60,7 @@ static int bmi270_spi_probe(struct spi_device *spi) + &bmi270_spi_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), +- "Failed to init i2c regmap"); ++ "Failed to init spi regmap\n"); + + return bmi270_core_probe(dev, regmap, chip_info); + } +-- +2.51.0 + diff --git a/queue-6.18/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-6.18/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..686bded029 --- /dev/null +++ b/queue-6.18/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From 17581ed0ca02c868b9109a9126f8f761fc134d21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 381b016fa5243..56244d49ab2fc 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -383,7 +383,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-6.18/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch b/queue-6.18/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch new file mode 100644 index 0000000000..4f6b02bfb0 --- /dev/null +++ b/queue-6.18/ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch @@ -0,0 +1,134 @@ +From 3ade3a066c4a97d51d6e8d1e19b826fd6c5a8dc7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 13:35:03 +0200 +Subject: ima: Attach CREDS_CHECK IMA hook to bprm_creds_from_file LSM hook + +From: Roberto Sassu + +[ Upstream commit 8f3fc4f3f8aa6e99266c69cc78bdaa58379e65fc ] + +Since commit 56305aa9b6fa ("exec: Compute file based creds only once"), the +credentials to be applied to the process after execution are not calculated +anymore for each step of finding intermediate interpreters (including the +final binary), but only after the final binary to be executed without +interpreter has been found. + +In particular, that means that the bprm_check_security LSM hook will not +see the updated cred->e[ug]id for the intermediate and for the final binary +to be executed, since the function doing this task has been moved from +prepare_binprm(), which calls the bprm_check_security hook, to +bprm_creds_from_file(). + +This breaks the IMA expectation for the CREDS_CHECK hook, introduced with +commit d906c10d8a31 ("IMA: Support using new creds in appraisal policy"), +which expects to evaluate "the credentials that will be committed when the +new process is started". This is clearly not the case for the CREDS_CHECK +IMA hook, which is attached to bprm_check_security. + +This issue does not affect systems which load a policy with the BPRM_CHECK +hook with no other criteria, as is the case with the built-in "tcb" and/or +"appraise_tcb" IMA policies. The "tcb" built-in policy measures all +executions regardless of the new credentials, and the "appraise_tcb" policy +is written in terms of the file owner, rather than IMA hooks. + +However, it does affect systems without a BPRM_CHECK policy rule or with a +BPRM_CHECK policy rule that does not include what CREDS_CHECK evaluates. As +an extreme example, taking a standalone rule like: + +measure func=CREDS_CHECK euid=0 + +This will not measure for example sudo (because CREDS_CHECK still sees the +bprm->cred->euid set to the regular user UID), but only the subsequent +commands after the euid was applied to the children. + +Make set[ug]id programs measured/appraised again by splitting +ima_bprm_check() in two separate hook implementations (CREDS_CHECK now +being implemented by ima_creds_check()), and by attaching CREDS_CHECK to +the bprm_creds_from_file LSM hook. + +The limitation of this approach is that CREDS_CHECK will not be invoked +anymore for the intermediate interpreters, like it was before, but only for +the final binary. This limitation can be removed only by reverting commit +56305aa9b6fa ("exec: Compute file based creds only once"). + +Link: https://github.com/linux-integrity/linux/issues/3 +Fixes: 56305aa9b6fa ("exec: Compute file based creds only once") +Cc: Serge E. Hallyn +Cc: Matthew Garrett +Cc: Eric W. Biederman +Cc: Jann Horn +Cc: Christian Brauner +Cc: Kees Cook +Signed-off-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_main.c | 42 ++++++++++++++++++++++++------- + 1 file changed, 33 insertions(+), 9 deletions(-) + +diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c +index cdd225f65a629..ebaebccfbe9ab 100644 +--- a/security/integrity/ima/ima_main.c ++++ b/security/integrity/ima/ima_main.c +@@ -573,18 +573,41 @@ static int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, + */ + static int ima_bprm_check(struct linux_binprm *bprm) + { +- int ret; + struct lsm_prop prop; + + security_current_getlsmprop_subj(&prop); +- ret = process_measurement(bprm->file, current_cred(), +- &prop, NULL, 0, MAY_EXEC, BPRM_CHECK); +- if (ret) +- return ret; +- +- security_cred_getlsmprop(bprm->cred, &prop); +- return process_measurement(bprm->file, bprm->cred, &prop, NULL, 0, +- MAY_EXEC, CREDS_CHECK); ++ return process_measurement(bprm->file, current_cred(), ++ &prop, NULL, 0, MAY_EXEC, BPRM_CHECK); ++} ++ ++/** ++ * ima_creds_check - based on policy, collect/store measurement. ++ * @bprm: contains the linux_binprm structure ++ * @file: contains the file descriptor of the binary being executed ++ * ++ * The OS protects against an executable file, already open for write, ++ * from being executed in deny_write_access() and an executable file, ++ * already open for execute, from being modified in get_write_access(). ++ * So we can be certain that what we verify and measure here is actually ++ * what is being executed. ++ * ++ * The difference from ima_bprm_check() is that ima_creds_check() is invoked ++ * only after determining the final binary to be executed without interpreter, ++ * and not when searching for intermediate binaries. The reason is that since ++ * commit 56305aa9b6fab ("exec: Compute file based creds only once"), the ++ * credentials to be applied to the process are calculated only at that stage ++ * (bprm_creds_from_file security hook instead of bprm_check_security). ++ * ++ * On success return 0. On integrity appraisal error, assuming the file ++ * is in policy and IMA-appraisal is in enforcing mode, return -EACCES. ++ */ ++static int ima_creds_check(struct linux_binprm *bprm, const struct file *file) ++{ ++ struct lsm_prop prop; ++ ++ security_current_getlsmprop_subj(&prop); ++ return process_measurement((struct file *)file, bprm->cred, &prop, NULL, ++ 0, MAY_EXEC, CREDS_CHECK); + } + + /** +@@ -1242,6 +1265,7 @@ static int __init init_ima(void) + static struct security_hook_list ima_hooks[] __ro_after_init = { + LSM_HOOK_INIT(bprm_check_security, ima_bprm_check), + LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec), ++ LSM_HOOK_INIT(bprm_creds_from_file, ima_creds_check), + LSM_HOOK_INIT(file_post_open, ima_file_check), + LSM_HOOK_INIT(inode_post_create_tmpfile, ima_post_create_tmpfile), + LSM_HOOK_INIT(file_release, ima_file_free), +-- +2.51.0 + diff --git a/queue-6.18/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-6.18/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..f171a9963d --- /dev/null +++ b/queue-6.18/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From cef88732cfc5c7c86db3c3a0de2240e1690a0618 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index 128fab8979308..db6d55af5a80b 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -674,7 +674,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-6.18/interconnect-debugfs-fix-incorrect-error-handling-fo.patch b/queue-6.18/interconnect-debugfs-fix-incorrect-error-handling-fo.patch new file mode 100644 index 0000000000..cb2ab086a6 --- /dev/null +++ b/queue-6.18/interconnect-debugfs-fix-incorrect-error-handling-fo.patch @@ -0,0 +1,53 @@ +From 646c31eab9965003eb05ea2e25334d21a0522a64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 23:14:47 +0800 +Subject: interconnect: debugfs: Fix incorrect error handling for NULL path + +From: Kuan-Wei Chiu + +[ Upstream commit 6bfe104fd0f94d0248af22c256ce725ee087157b ] + +The icc_commit_set() function, used by the debugfs interface, checks +the validity of the global cur_path pointer using IS_ERR_OR_NULL(). +However, in the specific case where cur_path is NULL, while +IS_ERR_OR_NULL(NULL) correctly evaluates to true, the subsequent call +to PTR_ERR(NULL) returns 0. + +This causes the function to return a success code (0) instead of an +error, misleading the user into believing their bandwidth request was +successfully committed when, in fact, no operation was performed. + +Fix this by adding an explicit check to return -EINVAL if cur_path is +NULL. This prevents silent failures and ensures that an invalid +operational sequence is immediately and clearly reported as an error. + +Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") +Signed-off-by: Kuan-Wei Chiu +Link: https://lore.kernel.org/r/20251010151447.2289779-1-visitorckw@gmail.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/debugfs-client.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c +index bc3fd8a7b9eb4..778deeb4a7e8a 100644 +--- a/drivers/interconnect/debugfs-client.c ++++ b/drivers/interconnect/debugfs-client.c +@@ -117,7 +117,12 @@ static int icc_commit_set(void *data, u64 val) + + mutex_lock(&debugfs_lock); + +- if (IS_ERR_OR_NULL(cur_path)) { ++ if (!cur_path) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (IS_ERR(cur_path)) { + ret = PTR_ERR(cur_path); + goto out; + } +-- +2.51.0 + diff --git a/queue-6.18/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch b/queue-6.18/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch new file mode 100644 index 0000000000..5456fef048 --- /dev/null +++ b/queue-6.18/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch @@ -0,0 +1,38 @@ +From ed8621728ab580549f8b296788cb75eb463ad337 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:00 +0300 +Subject: interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS + +From: Dmitry Baryshkov + +[ Upstream commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 ] + +>From the initial submission the interconnect driver missed the link from +SNOC_PNOC to the USB 2 configuration space. Add missing link in order to +let the platform configure and utilize this path. + +Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/msm8996.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c +index b73566c9b21f9..84cfafb22aa17 100644 +--- a/drivers/interconnect/qcom/msm8996.c ++++ b/drivers/interconnect/qcom/msm8996.c +@@ -552,6 +552,7 @@ static struct qcom_icc_node mas_venus_vmem = { + static const u16 mas_snoc_pnoc_links[] = { + MSM8996_SLAVE_BLSP_1, + MSM8996_SLAVE_BLSP_2, ++ MSM8996_SLAVE_USB_HS, + MSM8996_SLAVE_SDCC_1, + MSM8996_SLAVE_SDCC_2, + MSM8996_SLAVE_SDCC_4, +-- +2.51.0 + diff --git a/queue-6.18/io_uring-use-write_once-for-user-shared-memory.patch b/queue-6.18/io_uring-use-write_once-for-user-shared-memory.patch new file mode 100644 index 0000000000..b862af57c2 --- /dev/null +++ b/queue-6.18/io_uring-use-write_once-for-user-shared-memory.patch @@ -0,0 +1,52 @@ +From 2d079119360b602cf5fed00333e5d0d90b7290ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 12:58:19 +0000 +Subject: io_uring: use WRITE_ONCE for user shared memory + +From: Pavel Begunkov + +[ Upstream commit 93e197e524b14d185d011813b72773a1a49d932d ] + +IORING_SETUP_NO_MMAP rings remain user accessible even before the ctx +setup is finalised, so use WRITE_ONCE consistently when initialising +rings. + +Fixes: 03d89a2de25bb ("io_uring: support for user allocated memory for rings/sqes") +Signed-off-by: Pavel Begunkov +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 02339b74ba8d4..765abec2571f0 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -3623,10 +3623,6 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx, + + if (!(ctx->flags & IORING_SETUP_NO_SQARRAY)) + ctx->sq_array = (u32 *)((char *)rings + sq_array_offset); +- rings->sq_ring_mask = p->sq_entries - 1; +- rings->cq_ring_mask = p->cq_entries - 1; +- rings->sq_ring_entries = p->sq_entries; +- rings->cq_ring_entries = p->cq_entries; + + if (p->flags & IORING_SETUP_SQE128) + size = array_size(2 * sizeof(struct io_uring_sqe), p->sq_entries); +@@ -3649,6 +3645,12 @@ static __cold int io_allocate_scq_urings(struct io_ring_ctx *ctx, + return ret; + } + ctx->sq_sqes = io_region_get_ptr(&ctx->sq_region); ++ ++ memset(rings, 0, sizeof(*rings)); ++ WRITE_ONCE(rings->sq_ring_mask, ctx->sq_entries - 1); ++ WRITE_ONCE(rings->cq_ring_mask, ctx->cq_entries - 1); ++ WRITE_ONCE(rings->sq_ring_entries, ctx->sq_entries); ++ WRITE_ONCE(rings->cq_ring_entries, ctx->cq_entries); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.18/io_uring-zcrx-call-netdev_queue_get_dma_dev-under-in.patch b/queue-6.18/io_uring-zcrx-call-netdev_queue_get_dma_dev-under-in.patch new file mode 100644 index 0000000000..9983dd02a3 --- /dev/null +++ b/queue-6.18/io_uring-zcrx-call-netdev_queue_get_dma_dev-under-in.patch @@ -0,0 +1,81 @@ +From 7ae4654cef7d056d78cb12ccf60e9774786cd5c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 19:24:49 -0700 +Subject: io_uring/zcrx: call netdev_queue_get_dma_dev() under instance lock + +From: David Wei + +[ Upstream commit b6c5f9454ef34fd2753ba7843ef4d9a295c43eee ] + +netdev ops must be called under instance lock or rtnl_lock, but +io_register_zcrx_ifq() isn't doing this for netdev_queue_get_dma_dev(). +Fix this by taking the instance lock using netdev_get_by_index_lock(). + +Extended the instance lock section to include attaching a memory +provider. Could not move io_zcrx_create_area() outside, since the dmabuf +codepath IORING_ZCRX_AREA_DMABUF requires ifq->dev. + +Fixes: 59b8b32ac8d4 ("io_uring/zcrx: add support for custom DMA devices") +Signed-off-by: David Wei +Reviewed-by: Pavel Begunkov +Reviewed-by: Jakub Kicinski +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/zcrx.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c +index b1b723222cdb8..875ad40cf6591 100644 +--- a/io_uring/zcrx.c ++++ b/io_uring/zcrx.c +@@ -599,29 +599,30 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx, + if (ret) + goto err; + +- ifq->netdev = netdev_get_by_index(current->nsproxy->net_ns, reg.if_idx, +- &ifq->netdev_tracker, GFP_KERNEL); ++ ifq->netdev = netdev_get_by_index_lock(current->nsproxy->net_ns, reg.if_idx); + if (!ifq->netdev) { + ret = -ENODEV; + goto err; + } ++ netdev_hold(ifq->netdev, &ifq->netdev_tracker, GFP_KERNEL); + + ifq->dev = netdev_queue_get_dma_dev(ifq->netdev, reg.if_rxq); + if (!ifq->dev) { + ret = -EOPNOTSUPP; +- goto err; ++ goto netdev_put_unlock; + } + get_device(ifq->dev); + + ret = io_zcrx_create_area(ifq, &area); + if (ret) +- goto err; ++ goto netdev_put_unlock; + + mp_param.mp_ops = &io_uring_pp_zc_ops; + mp_param.mp_priv = ifq; +- ret = net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param); ++ ret = __net_mp_open_rxq(ifq->netdev, reg.if_rxq, &mp_param, NULL); + if (ret) +- goto err; ++ goto netdev_put_unlock; ++ netdev_unlock(ifq->netdev); + ifq->if_rxq = reg.if_rxq; + + reg.zcrx_id = id; +@@ -640,6 +641,9 @@ int io_register_zcrx_ifq(struct io_ring_ctx *ctx, + goto err; + } + return 0; ++netdev_put_unlock: ++ netdev_put(ifq->netdev, &ifq->netdev_tracker); ++ netdev_unlock(ifq->netdev); + err: + scoped_guard(mutex, &ctx->mmap_lock) + xa_erase(&ctx->zcrx_ctxs, id); +-- +2.51.0 + diff --git a/queue-6.18/iomap-allocate-s_dio_done_wq-for-async-reads-as-well.patch b/queue-6.18/iomap-allocate-s_dio_done_wq-for-async-reads-as-well.patch new file mode 100644 index 0000000000..6a865f03d7 --- /dev/null +++ b/queue-6.18/iomap-allocate-s_dio_done_wq-for-async-reads-as-well.patch @@ -0,0 +1,51 @@ +From a797c783b65b24da0e112862e2051e061d709d47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:00:13 +0100 +Subject: iomap: allocate s_dio_done_wq for async reads as well + +From: Christoph Hellwig + +[ Upstream commit 7fd8720dff2d9c70cf5a1a13b7513af01952ec02 ] + +Since commit 222f2c7c6d14 ("iomap: always run error completions in user +context"), read error completions are deferred to s_dio_done_wq. This +means the workqueue also needs to be allocated for async reads. + +Fixes: 222f2c7c6d14 ("iomap: always run error completions in user context") +Reported-by: syzbot+a2b9a4ed0d61b1efb3f5@syzkaller.appspotmail.com +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251124140013.902853-1-hch@lst.de +Tested-by: syzbot+a2b9a4ed0d61b1efb3f5@syzkaller.appspotmail.com +Reviewed-by: Dave Chinner +Reviewed-by: Darrick J. Wong +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index 143160042552b..6317e4cd42517 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -728,12 +728,12 @@ __iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter, + } + goto out_free_dio; + } ++ } + +- if (!wait_for_completion && !inode->i_sb->s_dio_done_wq) { +- ret = sb_init_dio_done_wq(inode->i_sb); +- if (ret < 0) +- goto out_free_dio; +- } ++ if (!wait_for_completion && !inode->i_sb->s_dio_done_wq) { ++ ret = sb_init_dio_done_wq(inode->i_sb); ++ if (ret < 0) ++ goto out_free_dio; + } + + inode_dio_begin(inode); +-- +2.51.0 + diff --git a/queue-6.18/iomap-always-run-error-completions-in-user-context.patch b/queue-6.18/iomap-always-run-error-completions-in-user-context.patch new file mode 100644 index 0000000000..adc909bf6b --- /dev/null +++ b/queue-6.18/iomap-always-run-error-completions-in-user-context.patch @@ -0,0 +1,51 @@ +From 29b8e1ab51359a2fbefd27d66d20e55f4fcb2933 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:06:27 +0100 +Subject: iomap: always run error completions in user context + +From: Christoph Hellwig + +[ Upstream commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a ] + +At least zonefs expects error completions to be able to sleep. Because +error completions aren't performance critical, just defer them to workqueue +context unconditionally. + +Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251113170633.1453259-3-hch@lst.de +Reviewed-by: Jan Kara +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index 5d5d63efbd576..143160042552b 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -179,7 +179,18 @@ static void iomap_dio_done(struct iomap_dio *dio) + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ return; ++ } ++ ++ /* ++ * Always run error completions in user context. These are not ++ * performance critical and some code relies on taking sleeping locks ++ * for error handling. ++ */ ++ if (dio->error) ++ dio->flags &= ~IOMAP_DIO_INLINE_COMP; ++ ++ if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); + } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { +-- +2.51.0 + diff --git a/queue-6.18/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch b/queue-6.18/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch new file mode 100644 index 0000000000..fd6714de8a --- /dev/null +++ b/queue-6.18/iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch @@ -0,0 +1,47 @@ +From 4dedc7d9124755205e8d400c5b8eea00218aa9b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 22:55:25 -0700 +Subject: iommu/amd: Fix potential out-of-bounds read in iommu_mmio_show + +From: Songtang Liu + +[ Upstream commit a0c7005333f9a968abb058b1d77bbcd7fb7fd1e7 ] + +In iommu_mmio_write(), it validates the user-provided offset with the +check: `iommu->dbg_mmio_offset > iommu->mmio_phys_end - 4`. +This assumes a 4-byte access. However, the corresponding +show handler, iommu_mmio_show(), uses readq() to perform an 8-byte +(64-bit) read. + +If a user provides an offset equal to `mmio_phys_end - 4`, the check +passes, and will lead to a 4-byte out-of-bounds read. + +Fix this by adjusting the boundary check to use sizeof(u64), which +corresponds to the size of the readq() operation. + +Fixes: 7a4ee419e8c1 ("iommu/amd: Add debugfs support to dump IOMMU MMIO registers") +Signed-off-by: Songtang Liu +Reviewed-by: Dheeraj Kumar Srivastava +Tested-by: Dheeraj Kumar Srivastava +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/amd/debugfs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/amd/debugfs.c b/drivers/iommu/amd/debugfs.c +index 10fa217a71199..20b04996441d6 100644 +--- a/drivers/iommu/amd/debugfs.c ++++ b/drivers/iommu/amd/debugfs.c +@@ -37,7 +37,7 @@ static ssize_t iommu_mmio_write(struct file *filp, const char __user *ubuf, + if (ret) + return ret; + +- if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - 4) { ++ if (iommu->dbg_mmio_offset > iommu->mmio_phys_end - sizeof(u64)) { + iommu->dbg_mmio_offset = -1; + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.18/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-6.18/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..8dbc788838 --- /dev/null +++ b/queue-6.18/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From ce09c6ecab73c86276348a4a4056d6e825cdf2d7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 57c097e876130..c939d0856b719 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -431,17 +431,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -464,6 +466,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-6.18/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch b/queue-6.18/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch new file mode 100644 index 0000000000..53ee8452ad --- /dev/null +++ b/queue-6.18/iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch @@ -0,0 +1,46 @@ +From 01027da33698d2ac7f91453b26edd441c0a5a66a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 11:09:17 -0800 +Subject: iommu/arm-smmu-v3: Fix error check in arm_smmu_alloc_cd_tables + +From: Ryan Huang + +[ Upstream commit 5941f0e0c1e0be03ebc15b461f64208f5250d3d9 ] + +In arm_smmu_alloc_cd_tables(), the error check following the +dma_alloc_coherent() for cd_table->l2.l1tab incorrectly tests +cd_table->l2.l2ptrs. + +This means an allocation failure for l1tab goes undetected, causing +the function to return 0 (success) erroneously. + +Correct the check to test cd_table->l2.l1tab. + +Fixes: e3b1be2e73db ("iommu/arm-smmu-v3: Reorganize struct arm_smmu_ctx_desc_cfg") +Signed-off-by: Daniel Mentz +Signed-off-by: Ryan Huang +Reviewed-by: Nicolin Chen +Reviewed-by: Pranjal Shrivastava +Reviewed-by: Jason Gunthorpe +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 2a8b46b948f05..9780f40ba3e65 100644 +--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c ++++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +@@ -1464,7 +1464,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) + cd_table->l2.l1tab = dma_alloc_coherent(smmu->dev, l1size, + &cd_table->cdtab_dma, + GFP_KERNEL); +- if (!cd_table->l2.l2ptrs) { ++ if (!cd_table->l2.l1tab) { + ret = -ENOMEM; + goto err_free_l2ptrs; + } +-- +2.51.0 + diff --git a/queue-6.18/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch b/queue-6.18/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch new file mode 100644 index 0000000000..dd7aff3b13 --- /dev/null +++ b/queue-6.18/iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch @@ -0,0 +1,39 @@ +From 63e58d008d7c7c5a20a8cdd29dd1f450e7b4a98f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:16:13 +0800 +Subject: iommu/vt-d: Fix unused invalidation hint in qi_desc_iotlb + +From: Aashish Sharma + +[ Upstream commit 6b38a108eeb3936b21643191db535a35dd7c890b ] + +Invalidation hint (ih) in the function 'qi_desc_iotlb' is initialized +to zero and never used. It is embedded in the 0th bit of the 'addr' +parameter. Get the correct 'ih' value from there. + +Fixes: f701c9f36bcb ("iommu/vt-d: Factor out invalidation descriptor composition") +Signed-off-by: Aashish Sharma +Link: https://lore.kernel.org/r/20251009010903.1323979-1-aashish@aashishsharma.net +Signed-off-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/intel/iommu.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h +index 3056583d7f56b..dcc5466d35f93 100644 +--- a/drivers/iommu/intel/iommu.h ++++ b/drivers/iommu/intel/iommu.h +@@ -1097,7 +1097,7 @@ static inline void qi_desc_iotlb(struct intel_iommu *iommu, u16 did, u64 addr, + struct qi_desc *desc) + { + u8 dw = 0, dr = 0; +- int ih = 0; ++ int ih = addr & 1; + + if (cap_write_drain(iommu->cap)) + dw = 1; +-- +2.51.0 + diff --git a/queue-6.18/iommu-vt-d-set-intel_iommu_floppy_wa-depend-on-blk_d.patch b/queue-6.18/iommu-vt-d-set-intel_iommu_floppy_wa-depend-on-blk_d.patch new file mode 100644 index 0000000000..1dc837bd8b --- /dev/null +++ b/queue-6.18/iommu-vt-d-set-intel_iommu_floppy_wa-depend-on-blk_d.patch @@ -0,0 +1,55 @@ +From e014dde33f93b42282fd243818aac50e6b835b97 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:16:12 +0800 +Subject: iommu/vt-d: Set INTEL_IOMMU_FLOPPY_WA depend on BLK_DEV_FD + +From: Vineeth Pillai (Google) + +[ Upstream commit cb3db5a39e2a6b6396df1780d39a250f649d2e3a ] + +INTEL_IOMMU_FLOPPY_WA workaround was introduced to create direct mappings +for first 16MB for floppy devices as the floppy drivers were not using +dma apis. We need not do this direct map if floppy driver is not +enabled. + +INTEL_IOMMU_FLOPPY_WA is generally not a good idea. Iommu will be +mapping pages in this address range while kernel would also be +allocating from this range(mostly on memory stress). A misbehaving +device using this domain will have access to the pages that the +kernel might be actively using. We noticed this while running a test +that was trying to figure out if any pages used by kernel is in iommu +page tables. + +This patch reduces the scope of the above issue by disabling the +workaround when floppy driver is not enabled. But we would still need to +fix the floppy driver to use dma apis so that we need not do direct map +without reserving the pages. Or the other option is to reserve this +memory range in firmware so that kernel will not use the pages. + +Fixes: d850c2ee5fe2 ("iommu/vt-d: Expose ISA direct mapping region via iommu_get_resv_regions") +Fixes: 49a0429e53f2 ("Intel IOMMU: Iommu floppy workaround") +Signed-off-by: Vineeth Pillai (Google) +Link: https://lore.kernel.org/r/20251002161625.1155133-1-vineeth@bitbyteword.org +Signed-off-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/intel/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iommu/intel/Kconfig b/drivers/iommu/intel/Kconfig +index f2f538c706503..17a91f881b2e9 100644 +--- a/drivers/iommu/intel/Kconfig ++++ b/drivers/iommu/intel/Kconfig +@@ -66,7 +66,7 @@ config INTEL_IOMMU_DEFAULT_ON + + config INTEL_IOMMU_FLOPPY_WA + def_bool y +- depends on X86 ++ depends on X86 && BLK_DEV_FD + help + Floppy disk drivers are known to bypass DMA API calls + thereby failing to work when IOMMU is enabled. This +-- +2.51.0 + diff --git a/queue-6.18/ipv6-clear-ra-flags-when-adding-a-static-route.patch b/queue-6.18/ipv6-clear-ra-flags-when-adding-a-static-route.patch new file mode 100644 index 0000000000..91b04bb43b --- /dev/null +++ b/queue-6.18/ipv6-clear-ra-flags-when-adding-a-static-route.patch @@ -0,0 +1,54 @@ +From 2658b64043ebdb961519ab0622de86c44f2ba1d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:59:38 +0100 +Subject: ipv6: clear RA flags when adding a static route + +From: Fernando Fernandez Mancera + +[ Upstream commit f72514b3c5698e4b900b25345e09f9ed33123de6 ] + +When an IPv6 Router Advertisement (RA) is received for a prefix, the +kernel creates the corresponding on-link route with flags RTF_ADDRCONF +and RTF_PREFIX_RT configured and RTF_EXPIRES if lifetime is set. + +If later a user configures a static IPv6 address on the same prefix the +kernel clears the RTF_EXPIRES flag but it doesn't clear the RTF_ADDRCONF +and RTF_PREFIX_RT. When the next RA for that prefix is received, the +kernel sees the route as RA-learned and wrongly configures back the +lifetime. This is problematic because if the route expires, the static +address won't have the corresponding on-link route. + +This fix clears the RTF_ADDRCONF and RTF_PREFIX_RT flags preventing that +the lifetime is configured when the next RA arrives. If the static +address is deleted, the route becomes RA-learned again. + +Fixes: 14ef37b6d00e ("ipv6: fix route lookup in addrconf_prefix_rcv()") +Reported-by: Garri Djavadyan +Closes: https://lore.kernel.org/netdev/ba807d39aca5b4dcf395cc11dca61a130a52cfd3.camel@gmail.com/ +Signed-off-by: Fernando Fernandez Mancera +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20251115095939.6967-1-fmancera@suse.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index 02c16909f6182..2111af022d946 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1138,6 +1138,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_set_expires(iter, rt->expires); + fib6_add_gc_list(iter); + } ++ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { ++ iter->fib6_flags &= ~RTF_ADDRCONF; ++ iter->fib6_flags &= ~RTF_PREFIX_RT; ++ } + + if (rt->fib6_pmtu) + fib6_metric_set(iter, RTAX_MTU, +-- +2.51.0 + diff --git a/queue-6.18/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch b/queue-6.18/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch new file mode 100644 index 0000000000..454c8dc650 --- /dev/null +++ b/queue-6.18/irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch @@ -0,0 +1,40 @@ +From e0ce286dc54c22b37c0b9efb9a65f818d789f821 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:01 +0200 +Subject: irqchip/bcm2712-mip: Fix OF node reference imbalance + +From: Johan Hovold + +[ Upstream commit 0435bcc4e5858c632c1b6d5afa637580d9779890 ] + +The init callback must not decrement the reference count of the provided +irqchip OF node. + +This should not cause any trouble currently, but if the driver ever +starts probe deferring it could lead to warnings about reference +underflow and saturation. + +Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm2712-mip.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c +index 9bd7bc0bf6d59..256c2d59f717d 100644 +--- a/drivers/irqchip/irq-bcm2712-mip.c ++++ b/drivers/irqchip/irq-bcm2712-mip.c +@@ -239,7 +239,6 @@ static int __init mip_of_msi_init(struct device_node *node, struct device_node * + int ret; + + pdev = of_find_device_by_node(node); +- of_node_put(node); + if (!pdev) + return -EPROBE_DEFER; + +-- +2.51.0 + diff --git a/queue-6.18/irqchip-bcm2712-mip-fix-section-mismatch.patch b/queue-6.18/irqchip-bcm2712-mip-fix-section-mismatch.patch new file mode 100644 index 0000000000..7216a7e24c --- /dev/null +++ b/queue-6.18/irqchip-bcm2712-mip-fix-section-mismatch.patch @@ -0,0 +1,37 @@ +From 576369c6a90fd7490aefa44acbcefc12edb35bdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:02 +0200 +Subject: irqchip/bcm2712-mip: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit a8452d1d59d46066051e676d5daa472cd08cb304 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm2712-mip.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c +index 256c2d59f717d..8466646e5a2da 100644 +--- a/drivers/irqchip/irq-bcm2712-mip.c ++++ b/drivers/irqchip/irq-bcm2712-mip.c +@@ -232,7 +232,7 @@ static int mip_parse_dt(struct mip_priv *mip, struct device_node *np) + return ret; + } + +-static int __init mip_of_msi_init(struct device_node *node, struct device_node *parent) ++static int mip_of_msi_init(struct device_node *node, struct device_node *parent) + { + struct platform_device *pdev; + struct mip_priv *mip; +-- +2.51.0 + diff --git a/queue-6.18/irqchip-drop-leftover-brackets.patch b/queue-6.18/irqchip-drop-leftover-brackets.patch new file mode 100644 index 0000000000..99b292c187 --- /dev/null +++ b/queue-6.18/irqchip-drop-leftover-brackets.patch @@ -0,0 +1,51 @@ +From 8ceafe96d7f007e7afd938a4ea51e01cf8cce6fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:10 +0200 +Subject: irqchip: Drop leftover brackets + +From: Johan Hovold + +[ Upstream commit 3540d99c03a88d4ebf65026f1f1926d3af658fb1 ] + +Drop some unnecessary brackets in platform_irqchip_probe() mistakenly +left by commit 9322d1915f9d ("irqchip: Plug a OF node reference leak in +platform_irqchip_probe()"). + +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Geert Uytterhoeven +Stable-dep-of: 1e3e330c0707 ("irqchip: Pass platform device to platform drivers") +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irqchip.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c +index 0ee7b6b71f5fa..652d20d2b07f1 100644 +--- a/drivers/irqchip/irqchip.c ++++ b/drivers/irqchip/irqchip.c +@@ -38,9 +38,8 @@ int platform_irqchip_probe(struct platform_device *pdev) + struct device_node *par_np __free(device_node) = of_irq_find_parent(np); + of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); + +- if (!irq_init_cb) { ++ if (!irq_init_cb) + return -EINVAL; +- } + + if (par_np == np) + par_np = NULL; +@@ -53,9 +52,8 @@ int platform_irqchip_probe(struct platform_device *pdev) + * interrupt controller. The actual initialization callback of this + * interrupt controller can check for specific domains as necessary. + */ +- if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { ++ if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) + return -EPROBE_DEFER; +- } + + return irq_init_cb(np, par_np); + } +-- +2.51.0 + diff --git a/queue-6.18/irqchip-imx-mu-msi-fix-section-mismatch.patch b/queue-6.18/irqchip-imx-mu-msi-fix-section-mismatch.patch new file mode 100644 index 0000000000..4806f12092 --- /dev/null +++ b/queue-6.18/irqchip-imx-mu-msi-fix-section-mismatch.patch @@ -0,0 +1,63 @@ +From 718840fb7a44eda35add73b3e71b0949cb01b67b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:06 +0200 +Subject: irqchip/imx-mu-msi: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 64acfd8e680ff8992c101fe19aadb112ce551072 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index d2a4e8a61a42b..41df168aa7da2 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -296,9 +296,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int __init imx_mu_of_init(struct device_node *dn, +- struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { + struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; +@@ -416,20 +415,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + } + +-static int __init imx_mu_imx6sx_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + } + +-static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + } +-- +2.51.0 + diff --git a/queue-6.18/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch b/queue-6.18/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch new file mode 100644 index 0000000000..e2cf43519b --- /dev/null +++ b/queue-6.18/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch @@ -0,0 +1,50 @@ +From 9af550df19daddf5150fed5e4ab7064f7a82585f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:03 +0200 +Subject: irqchip/irq-bcm7038-l1: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index 04fac0cc857fd..eda33bd5d080c 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -219,9 +219,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, + } + #endif + +-static int __init bcm7038_l1_init_one(struct device_node *dn, +- unsigned int idx, +- struct bcm7038_l1_chip *intc) ++static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, ++ struct bcm7038_l1_chip *intc) + { + struct resource res; + resource_size_t sz; +@@ -395,8 +394,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int __init bcm7038_l1_of_init(struct device_node *dn, +- struct device_node *parent) ++static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) + { + struct bcm7038_l1_chip *intc; + int idx, ret; +-- +2.51.0 + diff --git a/queue-6.18/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch b/queue-6.18/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..79afde236e --- /dev/null +++ b/queue-6.18/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch @@ -0,0 +1,79 @@ +From ac6d73adfa26aaff3968e0a367fe7d9e5ff3defc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:04 +0200 +Subject: irqchip/irq-bcm7120-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bfc0c5beab1fde843677923cf008f41d583c980a ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index ff22c31044018..b6c85560c42ea 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -143,8 +143,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + int ret; + +@@ -177,8 +176,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + unsigned int gc_idx; + +@@ -208,10 +206,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_probe(struct device_node *dn, +- struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, +- struct bcm7120_l2_intc_data *), ++ struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; +@@ -339,15 +336,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, + return ret; + } + +-static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); +-- +2.51.0 + diff --git a/queue-6.18/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch b/queue-6.18/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..6984774e88 --- /dev/null +++ b/queue-6.18/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch @@ -0,0 +1,58 @@ +From 8f9d30d040940668956c719162d6b7a8fce4dfb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:05 +0200 +Subject: irqchip/irq-brcmstb-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bbe1775924478e95372c2f896064ab6446000713 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index 1bec5b2cd3f0e..53e67c6c01f7a 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -138,10 +138,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable); + } + +-static int __init brcmstb_l2_intc_of_init(struct device_node *np, +- struct device_node *parent, +- const struct brcmstb_intc_init_params +- *init_params) ++static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; +@@ -257,14 +255,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, + return ret; + } + +-static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + } + +-static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + } +-- +2.51.0 + diff --git a/queue-6.18/irqchip-pass-platform-device-to-platform-drivers.patch b/queue-6.18/irqchip-pass-platform-device-to-platform-drivers.patch new file mode 100644 index 0000000000..6b2cd8474e --- /dev/null +++ b/queue-6.18/irqchip-pass-platform-device-to-platform-drivers.patch @@ -0,0 +1,589 @@ +From 11d8deb5be2d2a2404bdb758ff0aa4f8bc31e4c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:11 +0200 +Subject: irqchip: Pass platform device to platform drivers + +From: Johan Hovold + +[ Upstream commit 1e3e330c07076a0582385bbea029c9cc918fa30d ] + +The IRQCHIP_PLATFORM_DRIVER macros can be used to convert OF irqchip +drivers to platform drivers but currently reuse the OF init callback +prototype that only takes OF nodes as arguments. This forces drivers to +do reverse lookups of their struct devices during probe if they need +them for things like dev_printk() and device managed resources. + +Half of the drivers doing reverse lookups also currently fail to release +the additional reference taken during the lookup, while other drivers +have had the reference leak plugged in various ways (e.g. using +non-intuitive cleanup constructs which still confuse static checkers). + +Switch to using a probe callback that takes a platform device as its +first argument to simplify drivers and plug the remaining (mostly +benign) reference leaks. + +Fixes: 32c6c054661a ("irqchip: Add Broadcom BCM2712 MSI-X interrupt controller") +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Fixes: a6199bb514d8 ("irqchip: Add Qualcomm MPM controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Reviewed-by: Changhuang Liang +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm2712-mip.c | 10 ++----- + drivers/irqchip/irq-bcm7038-l1.c | 5 ++-- + drivers/irqchip/irq-bcm7120-l2.c | 20 ++++--------- + drivers/irqchip/irq-brcmstb-l2.c | 21 ++++++------- + drivers/irqchip/irq-imx-mu-msi.c | 24 +++++++-------- + drivers/irqchip/irq-mchp-eic.c | 5 ++-- + drivers/irqchip/irq-meson-gpio.c | 5 ++-- + drivers/irqchip/irq-qcom-mpm.c | 6 ++-- + drivers/irqchip/irq-renesas-rzg2l.c | 35 +++++++--------------- + drivers/irqchip/irq-renesas-rzv2h.c | 32 ++++++-------------- + drivers/irqchip/irq-starfive-jh8100-intc.c | 5 ++-- + drivers/irqchip/irqchip.c | 6 ++-- + drivers/irqchip/qcom-pdc.c | 5 ++-- + include/linux/irqchip.h | 8 ++++- + 14 files changed, 78 insertions(+), 109 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm2712-mip.c b/drivers/irqchip/irq-bcm2712-mip.c +index 8466646e5a2da..4761974ad650a 100644 +--- a/drivers/irqchip/irq-bcm2712-mip.c ++++ b/drivers/irqchip/irq-bcm2712-mip.c +@@ -232,16 +232,12 @@ static int mip_parse_dt(struct mip_priv *mip, struct device_node *np) + return ret; + } + +-static int mip_of_msi_init(struct device_node *node, struct device_node *parent) ++static int mip_msi_probe(struct platform_device *pdev, struct device_node *parent) + { +- struct platform_device *pdev; ++ struct device_node *node = pdev->dev.of_node; + struct mip_priv *mip; + int ret; + +- pdev = of_find_device_by_node(node); +- if (!pdev) +- return -EPROBE_DEFER; +- + mip = kzalloc(sizeof(*mip), GFP_KERNEL); + if (!mip) + return -ENOMEM; +@@ -284,7 +280,7 @@ static int mip_of_msi_init(struct device_node *node, struct device_node *parent) + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(mip_msi) +-IRQCHIP_MATCH("brcm,bcm2712-mip", mip_of_msi_init) ++IRQCHIP_MATCH("brcm,bcm2712-mip", mip_msi_probe) + IRQCHIP_PLATFORM_DRIVER_END(mip_msi) + MODULE_DESCRIPTION("Broadcom BCM2712 MSI-X interrupt controller"); + MODULE_AUTHOR("Phil Elwell "); +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index eda33bd5d080c..821b288587cab 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -394,8 +394,9 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) ++static int bcm7038_l1_probe(struct platform_device *pdev, struct device_node *parent) + { ++ struct device_node *dn = pdev->dev.of_node; + struct bcm7038_l1_chip *intc; + int idx, ret; + +@@ -453,7 +454,7 @@ static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(bcm7038_l1) +-IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_of_init) ++IRQCHIP_MATCH("brcm,bcm7038-l1-intc", bcm7038_l1_probe) + IRQCHIP_PLATFORM_DRIVER_END(bcm7038_l1) + MODULE_DESCRIPTION("Broadcom STB 7038-style L1/L2 interrupt controller"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index b6c85560c42ea..518c9d4366a55 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -206,14 +206,14 @@ static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_ + return 0; + } + +-static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct platform_device *pdev, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, + struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; ++ struct device_node *dn = pdev->dev.of_node; + struct bcm7120_l2_intc_data *data; +- struct platform_device *pdev; + struct irq_chip_generic *gc; + struct irq_chip_type *ct; + int ret = 0; +@@ -224,14 +224,7 @@ static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *par + if (!data) + return -ENOMEM; + +- pdev = of_find_device_by_node(dn); +- if (!pdev) { +- ret = -ENODEV; +- goto out_free_data; +- } +- + data->num_parent_irqs = platform_irq_count(pdev); +- put_device(&pdev->dev); + if (data->num_parent_irqs <= 0) { + pr_err("invalid number of parent interrupts\n"); + ret = -ENOMEM; +@@ -331,20 +324,19 @@ static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *par + if (data->map_base[idx]) + iounmap(data->map_base[idx]); + } +-out_free_data: + kfree(data); + return ret; + } + +-static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct platform_device *pdev, struct device_node *parent) + { +- return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, ++ return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct platform_device *pdev, struct device_node *parent) + { +- return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, ++ return bcm7120_l2_intc_probe(pdev, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); + } + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index 53e67c6c01f7a..bb7078d6524f9 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -138,11 +138,12 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_reg_writel(gc, ~b->saved_mask, ct->regs.enable); + } + +-static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, +- const struct brcmstb_intc_init_params *init_params) ++static int brcmstb_l2_intc_probe(struct platform_device *pdev, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; ++ struct device_node *np = pdev->dev.of_node; + struct brcmstb_l2_intc_data *data; + struct irq_chip_type *ct; + int ret; +@@ -255,21 +256,21 @@ static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *p + return ret; + } + +-static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) ++static int brcmstb_l2_edge_intc_probe(struct platform_device *pdev, struct device_node *parent) + { +- return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); ++ return brcmstb_l2_intc_probe(pdev, parent, &l2_edge_intc_init); + } + +-static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) ++static int brcmstb_l2_lvl_intc_probe(struct platform_device *pdev, struct device_node *parent) + { +- return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); ++ return brcmstb_l2_intc_probe(pdev, parent, &l2_lvl_intc_init); + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(brcmstb_l2) +-IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_of_init) +-IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_of_init) +-IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_of_init) +-IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_of_init) ++IRQCHIP_MATCH("brcm,l2-intc", brcmstb_l2_edge_intc_probe) ++IRQCHIP_MATCH("brcm,hif-spi-l2-intc", brcmstb_l2_edge_intc_probe) ++IRQCHIP_MATCH("brcm,upg-aux-aon-l2-intc", brcmstb_l2_edge_intc_probe) ++IRQCHIP_MATCH("brcm,bcm7271-l2-intc", brcmstb_l2_lvl_intc_probe) + IRQCHIP_PLATFORM_DRIVER_END(brcmstb_l2) + MODULE_DESCRIPTION("Broadcom STB generic L2 interrupt controller"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index 41df168aa7da2..c598f2f52fc6f 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -296,10 +296,9 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_probe(struct platform_device *pdev, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { +- struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; + struct device_link *pd_link_b; + struct imx_mu_msi *msi_data; +@@ -415,28 +414,27 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) ++static int imx_mu_imx7ulp_probe(struct platform_device *pdev, struct device_node *parent) + { +- return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); ++ return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx7ulp); + } + +-static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) ++static int imx_mu_imx6sx_probe(struct platform_device *pdev, struct device_node *parent) + { +- return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); ++ return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx6sx); + } + +-static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) ++static int imx_mu_imx8ulp_probe(struct platform_device *pdev, struct device_node *parent) + { +- return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); ++ return imx_mu_probe(pdev, parent, &imx_mu_cfg_imx8ulp); + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(imx_mu_msi) +-IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_of_init) +-IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_of_init) +-IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_of_init) ++IRQCHIP_MATCH("fsl,imx7ulp-mu-msi", imx_mu_imx7ulp_probe) ++IRQCHIP_MATCH("fsl,imx6sx-mu-msi", imx_mu_imx6sx_probe) ++IRQCHIP_MATCH("fsl,imx8ulp-mu-msi", imx_mu_imx8ulp_probe) + IRQCHIP_PLATFORM_DRIVER_END(imx_mu_msi, .pm = &imx_mu_pm_ops) + +- + MODULE_AUTHOR("Frank Li "); + MODULE_DESCRIPTION("Freescale MU MSI controller driver"); + MODULE_LICENSE("GPL"); +diff --git a/drivers/irqchip/irq-mchp-eic.c b/drivers/irqchip/irq-mchp-eic.c +index 516a3a0e359cc..b513a899c0853 100644 +--- a/drivers/irqchip/irq-mchp-eic.c ++++ b/drivers/irqchip/irq-mchp-eic.c +@@ -199,8 +199,9 @@ static const struct irq_domain_ops mchp_eic_domain_ops = { + .free = irq_domain_free_irqs_common, + }; + +-static int mchp_eic_init(struct device_node *node, struct device_node *parent) ++static int mchp_eic_probe(struct platform_device *pdev, struct device_node *parent) + { ++ struct device_node *node = pdev->dev.of_node; + struct irq_domain *parent_domain = NULL; + int ret, i; + +@@ -273,7 +274,7 @@ static int mchp_eic_init(struct device_node *node, struct device_node *parent) + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(mchp_eic) +-IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_init) ++IRQCHIP_MATCH("microchip,sama7g5-eic", mchp_eic_probe) + IRQCHIP_PLATFORM_DRIVER_END(mchp_eic) + + MODULE_DESCRIPTION("Microchip External Interrupt Controller"); +diff --git a/drivers/irqchip/irq-meson-gpio.c b/drivers/irqchip/irq-meson-gpio.c +index 7d177626d64ba..09ebf1d9c21b0 100644 +--- a/drivers/irqchip/irq-meson-gpio.c ++++ b/drivers/irqchip/irq-meson-gpio.c +@@ -572,8 +572,9 @@ static int meson_gpio_irq_parse_dt(struct device_node *node, struct meson_gpio_i + return 0; + } + +-static int meson_gpio_irq_of_init(struct device_node *node, struct device_node *parent) ++static int meson_gpio_irq_probe(struct platform_device *pdev, struct device_node *parent) + { ++ struct device_node *node = pdev->dev.of_node; + struct irq_domain *domain, *parent_domain; + struct meson_gpio_irq_controller *ctl; + int ret; +@@ -630,7 +631,7 @@ static int meson_gpio_irq_of_init(struct device_node *node, struct device_node * + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(meson_gpio_intc) +-IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_of_init) ++IRQCHIP_MATCH("amlogic,meson-gpio-intc", meson_gpio_irq_probe) + IRQCHIP_PLATFORM_DRIVER_END(meson_gpio_intc) + + MODULE_AUTHOR("Jerome Brunet "); +diff --git a/drivers/irqchip/irq-qcom-mpm.c b/drivers/irqchip/irq-qcom-mpm.c +index 8d569f7c5a7aa..83f31ea657b74 100644 +--- a/drivers/irqchip/irq-qcom-mpm.c ++++ b/drivers/irqchip/irq-qcom-mpm.c +@@ -320,9 +320,9 @@ static bool gic_hwirq_is_mapped(struct mpm_gic_map *maps, int cnt, u32 hwirq) + return false; + } + +-static int qcom_mpm_init(struct device_node *np, struct device_node *parent) ++static int qcom_mpm_probe(struct platform_device *pdev, struct device_node *parent) + { +- struct platform_device *pdev = of_find_device_by_node(np); ++ struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + struct irq_domain *parent_domain; + struct generic_pm_domain *genpd; +@@ -478,7 +478,7 @@ static int qcom_mpm_init(struct device_node *np, struct device_node *parent) + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_mpm) +-IRQCHIP_MATCH("qcom,mpm", qcom_mpm_init) ++IRQCHIP_MATCH("qcom,mpm", qcom_mpm_probe) + IRQCHIP_PLATFORM_DRIVER_END(qcom_mpm) + MODULE_DESCRIPTION("Qualcomm Technologies, Inc. MSM Power Manager"); + MODULE_LICENSE("GPL v2"); +diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c +index 12b6eb1503016..1bf19deb02c4e 100644 +--- a/drivers/irqchip/irq-renesas-rzg2l.c ++++ b/drivers/irqchip/irq-renesas-rzg2l.c +@@ -8,7 +8,6 @@ + */ + + #include +-#include + #include + #include + #include +@@ -528,18 +527,15 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, + return 0; + } + +-static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, +- const struct irq_chip *irq_chip) ++static int rzg2l_irqc_common_probe(struct platform_device *pdev, struct device_node *parent, ++ const struct irq_chip *irq_chip) + { +- struct platform_device *pdev = of_find_device_by_node(node); +- struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL; + struct irq_domain *irq_domain, *parent_domain; ++ struct device_node *node = pdev->dev.of_node; ++ struct device *dev = &pdev->dev; + struct reset_control *resetn; + int ret; + +- if (!pdev) +- return -ENODEV; +- + parent_domain = irq_find_host(parent); + if (!parent_domain) + return dev_err_probe(dev, -ENODEV, "cannot find parent domain\n"); +@@ -583,33 +579,22 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * + + register_syscore_ops(&rzg2l_irqc_syscore_ops); + +- /* +- * Prevent the cleanup function from invoking put_device by assigning +- * NULL to dev. +- * +- * make coccicheck will complain about missing put_device calls, but +- * those are false positives, as dev will be automatically "put" via +- * __free_put_device on the failing path. +- * On the successful path we don't actually want to "put" dev. +- */ +- dev = NULL; +- + return 0; + } + +-static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) ++static int rzg2l_irqc_probe(struct platform_device *pdev, struct device_node *parent) + { +- return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip); ++ return rzg2l_irqc_common_probe(pdev, parent, &rzg2l_irqc_chip); + } + +-static int rzfive_irqc_init(struct device_node *node, struct device_node *parent) ++static int rzfive_irqc_probe(struct platform_device *pdev, struct device_node *parent) + { +- return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip); ++ return rzg2l_irqc_common_probe(pdev, parent, &rzfive_irqc_chip); + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(rzg2l_irqc) +-IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_init) +-IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_init) ++IRQCHIP_MATCH("renesas,rzg2l-irqc", rzg2l_irqc_probe) ++IRQCHIP_MATCH("renesas,r9a07g043f-irqc", rzfive_irqc_probe) + IRQCHIP_PLATFORM_DRIVER_END(rzg2l_irqc) + MODULE_AUTHOR("Lad Prabhakar "); + MODULE_DESCRIPTION("Renesas RZ/G2L IRQC Driver"); +diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c +index 9018d9c3911e3..899a423b5da8f 100644 +--- a/drivers/irqchip/irq-renesas-rzv2h.c ++++ b/drivers/irqchip/irq-renesas-rzv2h.c +@@ -490,29 +490,15 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device + return 0; + } + +-static void rzv2h_icu_put_device(void *data) +-{ +- put_device(data); +-} +- +-static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent, +- const struct rzv2h_hw_info *hw_info) ++static int rzv2h_icu_probe_common(struct platform_device *pdev, struct device_node *parent, ++ const struct rzv2h_hw_info *hw_info) + { + struct irq_domain *irq_domain, *parent_domain; ++ struct device_node *node = pdev->dev.of_node; + struct rzv2h_icu_priv *rzv2h_icu_data; +- struct platform_device *pdev; + struct reset_control *resetn; + int ret; + +- pdev = of_find_device_by_node(node); +- if (!pdev) +- return -ENODEV; +- +- ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device, +- &pdev->dev); +- if (ret < 0) +- return ret; +- + parent_domain = irq_find_host(parent); + if (!parent_domain) { + dev_err(&pdev->dev, "cannot find parent domain\n"); +@@ -618,19 +604,19 @@ static const struct rzv2h_hw_info rzv2h_hw_params = { + .field_width = 8, + }; + +-static int rzg3e_icu_init(struct device_node *node, struct device_node *parent) ++static int rzg3e_icu_probe(struct platform_device *pdev, struct device_node *parent) + { +- return rzv2h_icu_init_common(node, parent, &rzg3e_hw_params); ++ return rzv2h_icu_probe_common(pdev, parent, &rzg3e_hw_params); + } + +-static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) ++static int rzv2h_icu_probe(struct platform_device *pdev, struct device_node *parent) + { +- return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params); ++ return rzv2h_icu_probe_common(pdev, parent, &rzv2h_hw_params); + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu) +-IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_init) +-IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init) ++IRQCHIP_MATCH("renesas,r9a09g047-icu", rzg3e_icu_probe) ++IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_probe) + IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu) + MODULE_AUTHOR("Fabrizio Castro "); + MODULE_DESCRIPTION("Renesas RZ/V2H(P) ICU Driver"); +diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c +index 117f2c651ebd0..705361b4ebe07 100644 +--- a/drivers/irqchip/irq-starfive-jh8100-intc.c ++++ b/drivers/irqchip/irq-starfive-jh8100-intc.c +@@ -114,8 +114,9 @@ static void starfive_intc_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static int starfive_intc_init(struct device_node *intc, struct device_node *parent) ++static int starfive_intc_probe(struct platform_device *pdev, struct device_node *parent) + { ++ struct device_node *intc = pdev->dev.of_node; + struct starfive_irq_chip *irqc; + struct reset_control *rst; + struct clk *clk; +@@ -198,7 +199,7 @@ static int starfive_intc_init(struct device_node *intc, struct device_node *pare + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(starfive_intc) +-IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_init) ++IRQCHIP_MATCH("starfive,jh8100-intc", starfive_intc_probe) + IRQCHIP_PLATFORM_DRIVER_END(starfive_intc) + + MODULE_DESCRIPTION("StarFive JH8100 External Interrupt Controller"); +diff --git a/drivers/irqchip/irqchip.c b/drivers/irqchip/irqchip.c +index 652d20d2b07f1..689c8e4489019 100644 +--- a/drivers/irqchip/irqchip.c ++++ b/drivers/irqchip/irqchip.c +@@ -36,9 +36,9 @@ int platform_irqchip_probe(struct platform_device *pdev) + { + struct device_node *np = pdev->dev.of_node; + struct device_node *par_np __free(device_node) = of_irq_find_parent(np); +- of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); ++ platform_irq_probe_t irq_probe = of_device_get_match_data(&pdev->dev); + +- if (!irq_init_cb) ++ if (!irq_probe) + return -EINVAL; + + if (par_np == np) +@@ -55,6 +55,6 @@ int platform_irqchip_probe(struct platform_device *pdev) + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) + return -EPROBE_DEFER; + +- return irq_init_cb(np, par_np); ++ return irq_probe(pdev, par_np); + } + EXPORT_SYMBOL_GPL(platform_irqchip_probe); +diff --git a/drivers/irqchip/qcom-pdc.c b/drivers/irqchip/qcom-pdc.c +index 52d77546aacb9..518f7f0f3dab5 100644 +--- a/drivers/irqchip/qcom-pdc.c ++++ b/drivers/irqchip/qcom-pdc.c +@@ -350,9 +350,10 @@ static int pdc_setup_pin_mapping(struct device_node *np) + + #define QCOM_PDC_SIZE 0x30000 + +-static int qcom_pdc_init(struct device_node *node, struct device_node *parent) ++static int qcom_pdc_probe(struct platform_device *pdev, struct device_node *parent) + { + struct irq_domain *parent_domain, *pdc_domain; ++ struct device_node *node = pdev->dev.of_node; + resource_size_t res_size; + struct resource res; + int ret; +@@ -428,7 +429,7 @@ static int qcom_pdc_init(struct device_node *node, struct device_node *parent) + } + + IRQCHIP_PLATFORM_DRIVER_BEGIN(qcom_pdc) +-IRQCHIP_MATCH("qcom,pdc", qcom_pdc_init) ++IRQCHIP_MATCH("qcom,pdc", qcom_pdc_probe) + IRQCHIP_PLATFORM_DRIVER_END(qcom_pdc) + MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Power Domain Controller"); + MODULE_LICENSE("GPL v2"); +diff --git a/include/linux/irqchip.h b/include/linux/irqchip.h +index d5e6024cb2a8c..bc4ddacd6ddc1 100644 +--- a/include/linux/irqchip.h ++++ b/include/linux/irqchip.h +@@ -17,12 +17,18 @@ + #include + #include + ++typedef int (*platform_irq_probe_t)(struct platform_device *, struct device_node *); ++ + /* Undefined on purpose */ + extern of_irq_init_cb_t typecheck_irq_init_cb; ++extern platform_irq_probe_t typecheck_irq_probe; + + #define typecheck_irq_init_cb(fn) \ + (__typecheck(typecheck_irq_init_cb, &fn) ? fn : fn) + ++#define typecheck_irq_probe(fn) \ ++ (__typecheck(typecheck_irq_probe, &fn) ? fn : fn) ++ + /* + * This macro must be used by the different irqchip drivers to declare + * the association between their DT compatible string and their +@@ -42,7 +48,7 @@ extern int platform_irqchip_probe(struct platform_device *pdev); + static const struct of_device_id drv_name##_irqchip_match_table[] = { + + #define IRQCHIP_MATCH(compat, fn) { .compatible = compat, \ +- .data = typecheck_irq_init_cb(fn), }, ++ .data = typecheck_irq_probe(fn), }, + + + #define IRQCHIP_PLATFORM_DRIVER_END(drv_name, ...) \ +-- +2.51.0 + diff --git a/queue-6.18/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-6.18/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..bb122b718d --- /dev/null +++ b/queue-6.18/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From 74f57cf1909627c522eb1674d0d88927142fea93 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-6.18/irqchip-renesas-rzg2l-fix-section-mismatch.patch b/queue-6.18/irqchip-renesas-rzg2l-fix-section-mismatch.patch new file mode 100644 index 0000000000..9edb68386a --- /dev/null +++ b/queue-6.18/irqchip-renesas-rzg2l-fix-section-mismatch.patch @@ -0,0 +1,45 @@ +From 245c7d552161eca4d5e8600908f12ef651d70ed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:07 +0200 +Subject: irqchip/renesas-rzg2l: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 5b338fbb2b5b21d61a9eaba14dcf43108de30258 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: d011c022efe27579 ("irqchip/renesas-rzg2l: Add support for RZ/Five SoC") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-renesas-rzg2l.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-renesas-rzg2l.c b/drivers/irqchip/irq-renesas-rzg2l.c +index 2a54adeb4cc71..12b6eb1503016 100644 +--- a/drivers/irqchip/irq-renesas-rzg2l.c ++++ b/drivers/irqchip/irq-renesas-rzg2l.c +@@ -597,14 +597,12 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * + return 0; + } + +-static int __init rzg2l_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzg2l_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzg2l_irqc_chip); + } + +-static int __init rzfive_irqc_init(struct device_node *node, +- struct device_node *parent) ++static int rzfive_irqc_init(struct device_node *node, struct device_node *parent) + { + return rzg2l_irqc_common_init(node, parent, &rzfive_irqc_chip); + } +-- +2.51.0 + diff --git a/queue-6.18/irqchip-starfive-jh8100-fix-section-mismatch.patch b/queue-6.18/irqchip-starfive-jh8100-fix-section-mismatch.patch new file mode 100644 index 0000000000..58e3bd82d3 --- /dev/null +++ b/queue-6.18/irqchip-starfive-jh8100-fix-section-mismatch.patch @@ -0,0 +1,38 @@ +From 3368ac52bdac85a49c148a9348a36be5aadfc6a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:08 +0200 +Subject: irqchip/starfive-jh8100: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit f798bdb9aa81c425184f92e3d0b44d3b53d10da7 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: e4e535036173 ("irqchip: Add StarFive external interrupt controller") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Changhuang Liang +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-starfive-jh8100-intc.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/irqchip/irq-starfive-jh8100-intc.c b/drivers/irqchip/irq-starfive-jh8100-intc.c +index 2460798ec158b..117f2c651ebd0 100644 +--- a/drivers/irqchip/irq-starfive-jh8100-intc.c ++++ b/drivers/irqchip/irq-starfive-jh8100-intc.c +@@ -114,8 +114,7 @@ static void starfive_intc_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static int __init starfive_intc_init(struct device_node *intc, +- struct device_node *parent) ++static int starfive_intc_init(struct device_node *intc, struct device_node *parent) + { + struct starfive_irq_chip *irqc; + struct reset_control *rst; +-- +2.51.0 + diff --git a/queue-6.18/kbuild-don-t-enable-cc_can_link-if-the-dummy-program.patch b/queue-6.18/kbuild-don-t-enable-cc_can_link-if-the-dummy-program.patch new file mode 100644 index 0000000000..38d95bde53 --- /dev/null +++ b/queue-6.18/kbuild-don-t-enable-cc_can_link-if-the-dummy-program.patch @@ -0,0 +1,57 @@ +From f194fb24cf4e6b32b5c7589780a4c7f0a1cb3a46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:43:56 +0100 +Subject: kbuild: don't enable CC_CAN_LINK if the dummy program generates + warnings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit d81d9d389b9b73acd68f300c8889c7fa1acd4977 ] + +It is possible that the kernel toolchain generates warnings when used +together with the system toolchain. This happens for example when the +older kernel toolchain does not handle new versions of sframe debug +information. While these warnings where ignored during the evaluation +of CC_CAN_LINK, together with CONFIG_WERROR the actual userprog build +will later fail. + +Example warning: + +.../x86_64-linux/13.2.0/../../../../x86_64-linux/bin/ld: +error in /lib/../lib64/crt1.o(.sframe); no .sframe will be created +collect2: error: ld returned 1 exit status + +Make sure that the very simple example program does not generate +warnings already to avoid breaking the userprog compilations. + +Fixes: ec4a3992bc0b ("kbuild: respect CONFIG_WERROR for linker and assembler") +Fixes: 3f0ff4cc6ffb ("kbuild: respect CONFIG_WERROR for userprogs") +Signed-off-by: Thomas Weißschuh +Reviewed-by: Nicolas Schier +Reviewed-by: Nathan Chancellor +Link: https://patch.msgid.link/20251114-kbuild-userprogs-bits-v3-1-4dee0d74d439@linutronix.de +Signed-off-by: Nicolas Schier +Signed-off-by: Sasha Levin +--- + scripts/cc-can-link.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/cc-can-link.sh b/scripts/cc-can-link.sh +index 6efcead319898..e67fd8d7b6841 100755 +--- a/scripts/cc-can-link.sh ++++ b/scripts/cc-can-link.sh +@@ -1,7 +1,7 @@ + #!/bin/sh + # SPDX-License-Identifier: GPL-2.0 + +-cat << "END" | $@ -x c - -o /dev/null >/dev/null 2>&1 ++cat << "END" | $@ -Werror -Wl,--fatal-warnings -x c - -o /dev/null >/dev/null 2>&1 + #include + int main(void) + { +-- +2.51.0 + diff --git a/queue-6.18/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch b/queue-6.18/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch new file mode 100644 index 0000000000..ee1313ec36 --- /dev/null +++ b/queue-6.18/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch @@ -0,0 +1,51 @@ +From 047ffe930df80627c714c931ea59c42aad8a37c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 08:13:32 -0700 +Subject: kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node + +From: Will Rosenberg + +[ Upstream commit 382b1e8f30f779af8d6d33268e53df7de579ef3c ] + +There exists a memory leak of kernfs_iattrs contained as an element +of kernfs_node allocated in __kernfs_new_node(). __kernfs_setattr() +allocates kernfs_iattrs as a sub-object, and the LSM security check +incorrectly errors out and does not free the kernfs_iattrs sub-object. + +Make an additional error out case that properly frees kernfs_iattrs if +security_kernfs_init_security() fails. + +Fixes: e19dfdc83b60 ("kernfs: initialize security of newly created nodes") +Co-developed-by: Oliver Rosenberg +Signed-off-by: Oliver Rosenberg +Signed-off-by: Will Rosenberg +Link: https://patch.msgid.link/20251125151332.2010687-1-whrosenb@asu.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/dir.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index a670ba3e565e0..5c0efd6b239f6 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -675,11 +675,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + if (parent) { + ret = security_kernfs_init_security(parent, kn); + if (ret) +- goto err_out3; ++ goto err_out4; + } + + return kn; + ++ err_out4: ++ simple_xattrs_free(&kn->iattr->xattrs, NULL); ++ kmem_cache_free(kernfs_iattrs_cache, kn->iattr); + err_out3: + spin_lock(&root->kernfs_idr_lock); + idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); +-- +2.51.0 + diff --git a/queue-6.18/landlock-fix-handling-of-disconnected-directories.patch b/queue-6.18/landlock-fix-handling-of-disconnected-directories.patch new file mode 100644 index 0000000000..1cf939d1dc --- /dev/null +++ b/queue-6.18/landlock-fix-handling-of-disconnected-directories.patch @@ -0,0 +1,171 @@ +From 7aaa6c4810808ffe58ed06301c5c0b53d2ca37b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 18:21:56 +0100 +Subject: landlock: Fix handling of disconnected directories +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Mickaël Salaün + +[ Upstream commit 49c9e09d961025b22e61ef9ad56aa1c21b6ce2f1 ] + +Disconnected files or directories can appear when they are visible and +opened from a bind mount, but have been renamed or moved from the source +of the bind mount in a way that makes them inaccessible from the mount +point (i.e. out of scope). + +Previously, access rights tied to files or directories opened through a +disconnected directory were collected by walking the related hierarchy +down to the root of the filesystem, without taking into account the +mount point because it couldn't be found. This could lead to +inconsistent access results, potential access right widening, and +hard-to-debug renames, especially since such paths cannot be printed. + +For a sandboxed task to create a disconnected directory, it needs to +have write access (i.e. FS_MAKE_REG, FS_REMOVE_FILE, and FS_REFER) to +the underlying source of the bind mount, and read access to the related +mount point. Because a sandboxed task cannot acquire more access +rights than those defined by its Landlock domain, this could lead to +inconsistent access rights due to missing permissions that should be +inherited from the mount point hierarchy, while inheriting permissions +from the filesystem hierarchy hidden by this mount point instead. + +Landlock now handles files and directories opened from disconnected +directories by taking into account the filesystem hierarchy when the +mount point is not found in the hierarchy walk, and also always taking +into account the mount point from which these disconnected directories +were opened. This ensures that a rename is not allowed if it would +widen access rights [1]. + +The rationale is that, even if disconnected hierarchies might not be +visible or accessible to a sandboxed task, relying on the collected +access rights from them improves the guarantee that access rights will +not be widened during a rename because of the access right comparison +between the source and the destination (see LANDLOCK_ACCESS_FS_REFER). +It may look like this would grant more access on disconnected files and +directories, but the security policies are always enforced for all the +evaluated hierarchies. This new behavior should be less surprising to +users and safer from an access control perspective. + +Remove a wrong WARN_ON_ONCE() canary in collect_domain_accesses() and +fix the related comment. + +Because opened files have their access rights stored in the related file +security properties, there is no impact for disconnected or unlinked +files. + +Cc: Christian Brauner +Cc: Günther Noack +Cc: Song Liu +Reported-by: Tingmao Wang +Closes: https://lore.kernel.org/r/027d5190-b37a-40a8-84e9-4ccbc352bcdf@maowtm.org +Closes: https://lore.kernel.org/r/09b24128f86973a6022e6aa8338945fcfb9a33e4.1749925391.git.m@maowtm.org +Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER") +Fixes: cb2c7d1a1776 ("landlock: Support filesystem access-control") +Link: https://lore.kernel.org/r/b0f46246-f2c5-42ca-93ce-0d629702a987@maowtm.org [1] +Reviewed-by: Tingmao Wang +Link: https://lore.kernel.org/r/20251128172200.760753-2-mic@digikod.net +Signed-off-by: Mickaël Salaün +Signed-off-by: Sasha Levin +--- + security/landlock/errata/abi-1.h | 16 +++++++++++++ + security/landlock/fs.c | 40 ++++++++++++++++++++++---------- + 2 files changed, 44 insertions(+), 12 deletions(-) + create mode 100644 security/landlock/errata/abi-1.h + +diff --git a/security/landlock/errata/abi-1.h b/security/landlock/errata/abi-1.h +new file mode 100644 +index 0000000000000..e8a2bff2e5b6a +--- /dev/null ++++ b/security/landlock/errata/abi-1.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++ ++/** ++ * DOC: erratum_3 ++ * ++ * Erratum 3: Disconnected directory handling ++ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ * ++ * This fix addresses an issue with disconnected directories that occur when a ++ * directory is moved outside the scope of a bind mount. The change ensures ++ * that evaluated access rights include both those from the disconnected file ++ * hierarchy down to its filesystem root and those from the related mount point ++ * hierarchy. This prevents access right widening through rename or link ++ * actions. ++ */ ++LANDLOCK_ERRATUM(3) +diff --git a/security/landlock/fs.c b/security/landlock/fs.c +index d9c12b993fa7d..a2ed0e76938aa 100644 +--- a/security/landlock/fs.c ++++ b/security/landlock/fs.c +@@ -909,21 +909,31 @@ static bool is_access_to_paths_allowed( + break; + } + } ++ + if (unlikely(IS_ROOT(walker_path.dentry))) { +- /* +- * Stops at disconnected root directories. Only allows +- * access to internal filesystems (e.g. nsfs, which is +- * reachable through /proc//ns/). +- */ +- if (walker_path.mnt->mnt_flags & MNT_INTERNAL) { ++ if (likely(walker_path.mnt->mnt_flags & MNT_INTERNAL)) { ++ /* ++ * Stops and allows access when reaching disconnected root ++ * directories that are part of internal filesystems (e.g. nsfs, ++ * which is reachable through /proc//ns/). ++ */ + allowed_parent1 = true; + allowed_parent2 = true; ++ break; + } +- break; ++ ++ /* ++ * We reached a disconnected root directory from a bind mount. ++ * Let's continue the walk with the mount point we missed. ++ */ ++ dput(walker_path.dentry); ++ walker_path.dentry = walker_path.mnt->mnt_root; ++ dget(walker_path.dentry); ++ } else { ++ parent_dentry = dget_parent(walker_path.dentry); ++ dput(walker_path.dentry); ++ walker_path.dentry = parent_dentry; + } +- parent_dentry = dget_parent(walker_path.dentry); +- dput(walker_path.dentry); +- walker_path.dentry = parent_dentry; + } + path_put(&walker_path); + +@@ -1021,6 +1031,9 @@ static access_mask_t maybe_remove(const struct dentry *const dentry) + * file. While walking from @dir to @mnt_root, we record all the domain's + * allowed accesses in @layer_masks_dom. + * ++ * Because of disconnected directories, this walk may not reach @mnt_dir. In ++ * this case, the walk will continue to @mnt_dir after this call. ++ * + * This is similar to is_access_to_paths_allowed() but much simpler because it + * only handles walking on the same mount point and only checks one set of + * accesses. +@@ -1062,8 +1075,11 @@ static bool collect_domain_accesses( + break; + } + +- /* We should not reach a root other than @mnt_root. */ +- if (dir == mnt_root || WARN_ON_ONCE(IS_ROOT(dir))) ++ /* ++ * Stops at the mount point or the filesystem root for a disconnected ++ * directory. ++ */ ++ if (dir == mnt_root || unlikely(IS_ROOT(dir))) + break; + + parent_dentry = dget_parent(dir); +-- +2.51.0 + diff --git a/queue-6.18/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-6.18/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..75b2af334a --- /dev/null +++ b/queue-6.18/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From e7aebe823ff7a99e5bd6d3d80ed0c9e49cb81b9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index e95287416ef87..99df46f2d9f52 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-6.18/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch b/queue-6.18/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch new file mode 100644 index 0000000000..f866570ae7 --- /dev/null +++ b/queue-6.18/leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch @@ -0,0 +1,51 @@ +From 595fa3512330221a323abf1b7be07a81de0fa9ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:06:43 +0800 +Subject: leds: rgb: leds-qcom-lpg: Don't enable TRILED when configuring PWM + +From: Fenglin Wu + +[ Upstream commit 072cd5f458d76b9e15d89ebdaea8b5cb1312eeef ] + +The PWM signal from the LPG channel can be routed to PMIC GPIOs with +proper GPIO configuration, and it is not necessary to enable the +TRILED channel in that case. This also applies to the LPG channels +that mapped to TRILED channels. Additionally, enabling the TRILED +channel unnecessarily would cause a voltage increase in its power +supply. Hence remove it. + +Fixes: 24e2d05d1b68 ("leds: Add driver for Qualcomm LPG") +Signed-off-by: Fenglin Wu +Reviewed-by: Bjorn Andersson +Link: https://patch.msgid.link/20251119-lpg_triled_fix-v3-2-84b6dbdc774a@oss.qualcomm.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/rgb/leds-qcom-lpg.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c +index 4f2a178e3d265..e197f548cddb0 100644 +--- a/drivers/leds/rgb/leds-qcom-lpg.c ++++ b/drivers/leds/rgb/leds-qcom-lpg.c +@@ -2,7 +2,7 @@ + /* + * Copyright (c) 2017-2022 Linaro Ltd + * Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. +- * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -1247,8 +1247,6 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + + lpg_apply(chan); + +- triled_set(lpg, chan->triled_mask, chan->enabled ? chan->triled_mask : 0); +- + out_unlock: + mutex_unlock(&lpg->lock); + +-- +2.51.0 + diff --git a/queue-6.18/leds-upboard-fix-module-alias.patch b/queue-6.18/leds-upboard-fix-module-alias.patch new file mode 100644 index 0000000000..b81a455d1a --- /dev/null +++ b/queue-6.18/leds-upboard-fix-module-alias.patch @@ -0,0 +1,36 @@ +From 7e6144e59c7413db60a2eb705908a3d633ca1ce7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 17:36:25 +0200 +Subject: leds: upboard: Fix module alias + +From: Thomas Richard + +[ Upstream commit c06a017439110debd335b6864bc2d69835624235 ] + +The module alias does not match the cell name defined in the MFD driver, +preventing automatic loading when the driver is built as a module. So fix +the module alias to ensure proper module auto-loading. + +Fixes: 0ef2929a0181 ("leds: Add AAEON UP board LED driver") +Signed-off-by: Thomas Richard +Reviewed-by: Krzysztof Kozlowski +Link: https://patch.msgid.link/20251020-leds-upboard-fix-module-alias-v2-1-84ac5c3a1a81@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-upboard.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/leds/leds-upboard.c b/drivers/leds/leds-upboard.c +index b350eb294280f..12989b2f19530 100644 +--- a/drivers/leds/leds-upboard.c ++++ b/drivers/leds/leds-upboard.c +@@ -123,4 +123,4 @@ MODULE_AUTHOR("Gary Wang "); + MODULE_AUTHOR("Thomas Richard "); + MODULE_DESCRIPTION("UP Board LED driver"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:upboard-led"); ++MODULE_ALIAS("platform:upboard-leds"); +-- +2.51.0 + diff --git a/queue-6.18/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-6.18/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..15ea9734bf --- /dev/null +++ b/queue-6.18/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From 972f5f3e88ab2f696b18d729727c3b0216dc5aea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index eb0cb11d0d126..a356965c1d734 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1928,9 +1928,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1996,6 +1993,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-6.18/libbpf-fix-parsing-of-multi-split-btf.patch b/queue-6.18/libbpf-fix-parsing-of-multi-split-btf.patch new file mode 100644 index 0000000000..1116e3c83b --- /dev/null +++ b/queue-6.18/libbpf-fix-parsing-of-multi-split-btf.patch @@ -0,0 +1,51 @@ +From bb4d16e72ac904c60294963313513b61e6abe9e0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 20:33:08 +0000 +Subject: libbpf: Fix parsing of multi-split BTF + +From: Alan Maguire + +[ Upstream commit 4f596acc260e691a2e348f64230392f3472feea3 ] + +When creating multi-split BTF we correctly set the start string offset +to be the size of the base string section plus the base BTF start +string offset; the latter is needed for multi-split BTF since the +offset is non-zero there. + +Unfortunately the BTF parsing case needed that logic and it was +missed. + +Fixes: 4e29128a9ace ("libbpf/btf: Fix string handling to support multi-split BTF") +Signed-off-by: Alan Maguire +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20251104203309.318429-2-alan.maguire@oracle.com +Signed-off-by: Sasha Levin +--- + tools/lib/bpf/btf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c +index 18907f0fcf9f0..9f141395c074e 100644 +--- a/tools/lib/bpf/btf.c ++++ b/tools/lib/bpf/btf.c +@@ -1061,7 +1061,7 @@ static struct btf *btf_new(const void *data, __u32 size, struct btf *base_btf, b + if (base_btf) { + btf->base_btf = base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + if (is_mmap) { +@@ -5818,7 +5818,7 @@ void btf_set_base_btf(struct btf *btf, const struct btf *base_btf) + { + btf->base_btf = (struct btf *)base_btf; + btf->start_id = btf__type_cnt(base_btf); +- btf->start_str_off = base_btf->hdr->str_len; ++ btf->start_str_off = base_btf->hdr->str_len + base_btf->start_str_off; + } + + int btf__relocate(struct btf *btf, const struct btf *base_btf) +-- +2.51.0 + diff --git a/queue-6.18/locktorture-fix-memory-leak-in-param_set_cpumask.patch b/queue-6.18/locktorture-fix-memory-leak-in-param_set_cpumask.patch new file mode 100644 index 0000000000..1585dc6cbd --- /dev/null +++ b/queue-6.18/locktorture-fix-memory-leak-in-param_set_cpumask.patch @@ -0,0 +1,84 @@ +From 7f70b10f13fd58efdccb1c584131e8dc9347b453 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 12:19:56 -0800 +Subject: locktorture: Fix memory leak in param_set_cpumask() + +From: Wang Liang + +[ Upstream commit e52b43883d084a9af263c573f2a1bd1ca5088389 ] + +With CONFIG_CPUMASK_OFFSTACK=y, the 'bind_writers' buffer is allocated via +alloc_cpumask_var() in param_set_cpumask(). But it is not freed, when +setting the module parameter multiple times by sysfs interface or removing +module. + +Below kmemleak trace is seen for this issue: + +unreferenced object 0xffff888100aabff8 (size 8): + comm "bash", pid 323, jiffies 4295059233 + hex dump (first 8 bytes): + 07 00 00 00 00 00 00 00 ........ + backtrace (crc ac50919): + __kmalloc_node_noprof+0x2e5/0x420 + alloc_cpumask_var_node+0x1f/0x30 + param_set_cpumask+0x26/0xb0 [locktorture] + param_attr_store+0x93/0x100 + module_attr_store+0x1b/0x30 + kernfs_fop_write_iter+0x114/0x1b0 + vfs_write+0x300/0x410 + ksys_write+0x60/0xd0 + do_syscall_64+0xa4/0x260 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +This issue can be reproduced by: + insmod locktorture.ko bind_writers=1 + rmmod locktorture + +or: + insmod locktorture.ko bind_writers=1 + echo 2 > /sys/module/locktorture/parameters/bind_writers + +Considering that setting the module parameter 'bind_writers' or +'bind_readers' by sysfs interface has no real effect, set the parameter +permissions to 0444. To fix the memory leak when removing module, free +'bind_writers' and 'bind_readers' memory in lock_torture_cleanup(). + +Fixes: 73e341242483 ("locktorture: Add readers_bind and writers_bind module parameters") +Suggested-by: Zhang Changzhong +Signed-off-by: Wang Liang +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/locking/locktorture.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/kernel/locking/locktorture.c b/kernel/locking/locktorture.c +index ce0362f0a8719..6567e5eeacc0e 100644 +--- a/kernel/locking/locktorture.c ++++ b/kernel/locking/locktorture.c +@@ -103,8 +103,8 @@ static const struct kernel_param_ops lt_bind_ops = { + .get = param_get_cpumask, + }; + +-module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0644); +-module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0644); ++module_param_cb(bind_readers, <_bind_ops, &bind_readers, 0444); ++module_param_cb(bind_writers, <_bind_ops, &bind_writers, 0444); + + long torture_sched_setaffinity(pid_t pid, const struct cpumask *in_mask, bool dowarn); + +@@ -1211,6 +1211,10 @@ static void lock_torture_cleanup(void) + cxt.cur_ops->exit(); + cxt.init_called = false; + } ++ ++ free_cpumask_var(bind_readers); ++ free_cpumask_var(bind_writers); ++ + torture_cleanup_end(); + } + +-- +2.51.0 + diff --git a/queue-6.18/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-6.18/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..06ff76110c --- /dev/null +++ b/queue-6.18/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From af2b9b50801fefe784073a86954d13b53f1f6fbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index 369d72f59b3c1..06fd910b3fd1a 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -187,13 +187,14 @@ static int mac_hid_toggle_emumouse(const struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-6.18/md-avoid-repeated-calls-to-del_gendisk.patch b/queue-6.18/md-avoid-repeated-calls-to-del_gendisk.patch new file mode 100644 index 0000000000..99dec459ef --- /dev/null +++ b/queue-6.18/md-avoid-repeated-calls-to-del_gendisk.patch @@ -0,0 +1,76 @@ +From b51822ee42d13cbebe50b8bbfde96beb8c03d135 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 14:34:19 +0800 +Subject: md: avoid repeated calls to del_gendisk + +From: Xiao Ni + +[ Upstream commit 90e3bb44c0a86e245d8e5c6520206fa113acb1ee ] + +There is a uaf problem which is found by case 23rdev-lifetime: + +Oops: general protection fault, probably for non-canonical address 0xdead000000000122 +RIP: 0010:bdi_unregister+0x4b/0x170 +Call Trace: + + __del_gendisk+0x356/0x3e0 + mddev_unlock+0x351/0x360 + rdev_attr_store+0x217/0x280 + kernfs_fop_write_iter+0x14a/0x210 + vfs_write+0x29e/0x550 + ksys_write+0x74/0xf0 + do_syscall_64+0xbb/0x380 + entry_SYSCALL_64_after_hwframe+0x77/0x7f +RIP: 0033:0x7ff5250a177e + +The sequence is: +1. rdev remove path gets reconfig_mutex +2. rdev remove path release reconfig_mutex in mddev_unlock +3. md stop calls do_md_stop and sets MD_DELETED +4. rdev remove path calls del_gendisk because MD_DELETED is set +5. md stop path release reconfig_mutex and calls del_gendisk again + +So there is a race condition we should resolve. This patch adds a +flag MD_DO_DELETE to avoid the race condition. + +Link: https://lore.kernel.org/linux-raid/20251029063419.21700-1-xni@redhat.com +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Signed-off-by: Xiao Ni +Suggested-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 3 ++- + drivers/md/md.h | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 6062e0deb6160..5d40beaecc9c7 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -941,7 +941,8 @@ void mddev_unlock(struct mddev *mddev) + * do_md_stop. dm raid only uses md_stop to stop. So dm raid + * doesn't need to check MD_DELETED when getting reconfig lock + */ +- if (test_bit(MD_DELETED, &mddev->flags)) { ++ if (test_bit(MD_DELETED, &mddev->flags) && ++ !test_and_set_bit(MD_DO_DELETE, &mddev->flags)) { + kobject_del(&mddev->kobj); + del_gendisk(mddev->gendisk); + } +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 5d5f780b84477..fd6e001c1d38f 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -354,6 +354,7 @@ enum mddev_flags { + MD_HAS_MULTIPLE_PPLS, + MD_NOT_READY, + MD_BROKEN, ++ MD_DO_DELETE, + MD_DELETED, + }; + +-- +2.51.0 + diff --git a/queue-6.18/md-delete-md_redundancy_group-when-array-is-becoming.patch b/queue-6.18/md-delete-md_redundancy_group-when-array-is-becoming.patch new file mode 100644 index 0000000000..a2230c4967 --- /dev/null +++ b/queue-6.18/md-delete-md_redundancy_group-when-array-is-becoming.patch @@ -0,0 +1,69 @@ +From 10f4dc0368e9831a6762cbb7da3788646d6bffb0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 20:57:53 +0800 +Subject: md: delete md_redundancy_group when array is becoming inactive + +From: Li Nan + +[ Upstream commit 0ce112d9171ad766d4c6716951e73f91a0bfc184 ] + +'md_redundancy_group' are created in md_run() and deleted in del_gendisk(), +but these are not paired. Writing inactive/active to sysfs array_state can +trigger md_run() multiple times without del_gendisk(), leading to +duplicate creation as below: + + sysfs: cannot create duplicate filename '/devices/virtual/block/md0/md/sync_action' + Call Trace: + dump_stack_lvl+0x9f/0x120 + dump_stack+0x14/0x20 + sysfs_warn_dup+0x96/0xc0 + sysfs_add_file_mode_ns+0x19c/0x1b0 + internal_create_group+0x213/0x830 + sysfs_create_group+0x17/0x20 + md_run+0x856/0xe60 + ? __x64_sys_openat+0x23/0x30 + do_md_run+0x26/0x1d0 + array_state_store+0x559/0x760 + md_attr_store+0xc9/0x1e0 + sysfs_kf_write+0x6f/0xa0 + kernfs_fop_write_iter+0x141/0x2a0 + vfs_write+0x1fc/0x5a0 + ksys_write+0x79/0x180 + __x64_sys_write+0x1d/0x30 + x64_sys_call+0x2818/0x2880 + do_syscall_64+0xa9/0x580 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + md: cannot register extra attributes for md0 + +Creation of it depends on 'pers', its lifecycle cannot be aligned with +gendisk. So fix this issue by triggering 'md_redundancy_group' deletion +when the array is becoming inactive. + +Link: https://lore.kernel.org/linux-raid/20251103125757.1405796-2-linan666@huaweicloud.com +Fixes: 790abe4d77af ("md: remove/add redundancy group only in level change") +Signed-off-by: Li Nan +Reviewed-by: Xiao Ni +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 5d40beaecc9c7..7b21eb1dbc533 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -6872,6 +6872,10 @@ static int do_md_stop(struct mddev *mddev, int mode) + if (!md_is_rdwr(mddev)) + set_disk_ro(disk, 0); + ++ if (mode == 2 && mddev->pers->sync_request && ++ mddev->to_remove == NULL) ++ mddev->to_remove = &md_redundancy_group; ++ + __md_stop_writes(mddev); + __md_stop(mddev); + +-- +2.51.0 + diff --git a/queue-6.18/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch b/queue-6.18/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch new file mode 100644 index 0000000000..5844e62c70 --- /dev/null +++ b/queue-6.18/md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch @@ -0,0 +1,60 @@ +From 93633d38c12c1f305baebc5c0a7d0e22d97c4c0c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 09:24:24 +0800 +Subject: md: delete mddev kobj before deleting gendisk kobj + +From: Xiao Ni + +[ Upstream commit cc394b94dc40b661efc9895665abf03640ffff2d ] + +In sync del gendisk path, it deletes gendisk first and the directory +/sys/block/md is removed. Then it releases mddev kobj in a delayed work. +If we enable debug log in sysfs_remove_group, we can see the debug log +'sysfs group bitmap not found for kobject md'. It's the reason that the +parent kobj has been deleted, so it can't find parent directory. + +In creating path, it allocs gendisk first, then adds mddev kobj. So it +should delete mddev kobj before deleting gendisk. + +Before commit 9e59d609763f ("md: call del_gendisk in control path"), it +releases mddev kobj first. If the kobj hasn't been deleted, it does clean +job and deletes the kobj. Then it calls del_gendisk and releases gendisk +kobj. So it doesn't need to call kobject_del to delete mddev kobj. After +this patch, in sync del gendisk path, the sequence changes. So it needs +to call kobject_del to delete mddev kobj. + +After this patch, the sequence is: +1. kobject del mddev kobj +2. del_gendisk deletes gendisk kobj +3. mddev_delayed_delete releases mddev kobj +4. md_kobj_release releases gendisk kobj + +Link: https://lore.kernel.org/linux-raid/20250928012424.61370-1-xni@redhat.com +Fixes: 9e59d609763f ("md: call del_gendisk in control path") +Signed-off-by: Xiao Ni +Reviewed-by: Li Nan +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 41c476b40c7a3..8128c8839a082 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -941,8 +941,10 @@ void mddev_unlock(struct mddev *mddev) + * do_md_stop. dm raid only uses md_stop to stop. So dm raid + * doesn't need to check MD_DELETED when getting reconfig lock + */ +- if (test_bit(MD_DELETED, &mddev->flags)) ++ if (test_bit(MD_DELETED, &mddev->flags)) { ++ kobject_del(&mddev->kobj); + del_gendisk(mddev->gendisk); ++ } + } + } + EXPORT_SYMBOL_GPL(mddev_unlock); +-- +2.51.0 + diff --git a/queue-6.18/md-fix-rcu-protection-in-md_wakeup_thread.patch b/queue-6.18/md-fix-rcu-protection-in-md_wakeup_thread.patch new file mode 100644 index 0000000000..57816601f8 --- /dev/null +++ b/queue-6.18/md-fix-rcu-protection-in-md_wakeup_thread.patch @@ -0,0 +1,114 @@ +From f6f928d97a638d337a69c3d7bf8fb423226defd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 16:32:27 +0800 +Subject: md: fix rcu protection in md_wakeup_thread + +From: Yun Zhou + +[ Upstream commit 0dc76205549b4c25705e54345f211b9f66e018a0 ] + +We attempted to use RCU to protect the pointer 'thread', but directly +passed the value when calling md_wakeup_thread(). This means that the +RCU pointer has been acquired before rcu_read_lock(), which renders +rcu_read_lock() ineffective and could lead to a use-after-free. + +Link: https://lore.kernel.org/linux-raid/20251015083227.1079009-1-yun.zhou@windriver.com +Fixes: 446931543982 ("md: protect md_thread with rcu") +Signed-off-by: Yun Zhou +Reviewed-by: Li Nan +Reviewed-by: Yu Kuai +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 14 ++++++-------- + drivers/md/md.h | 8 +++++++- + 2 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 8128c8839a082..6062e0deb6160 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -99,7 +99,7 @@ static int remove_and_add_spares(struct mddev *mddev, + struct md_rdev *this); + static void mddev_detach(struct mddev *mddev); + static void export_rdev(struct md_rdev *rdev, struct mddev *mddev); +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread); ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread); + + /* + * Default number of read corrections we'll attempt on an rdev +@@ -5136,7 +5136,7 @@ static void stop_sync_thread(struct mddev *mddev, bool locked) + * Thread might be blocked waiting for metadata update which will now + * never happen + */ +- md_wakeup_thread_directly(mddev->sync_thread); ++ md_wakeup_thread_directly(&mddev->sync_thread); + if (work_pending(&mddev->sync_work)) + flush_work(&mddev->sync_work); + +@@ -8375,22 +8375,21 @@ static int md_thread(void *arg) + return 0; + } + +-static void md_wakeup_thread_directly(struct md_thread __rcu *thread) ++static void md_wakeup_thread_directly(struct md_thread __rcu **thread) + { + struct md_thread *t; + + rcu_read_lock(); +- t = rcu_dereference(thread); ++ t = rcu_dereference(*thread); + if (t) + wake_up_process(t->tsk); + rcu_read_unlock(); + } + +-void md_wakeup_thread(struct md_thread __rcu *thread) ++void __md_wakeup_thread(struct md_thread __rcu *thread) + { + struct md_thread *t; + +- rcu_read_lock(); + t = rcu_dereference(thread); + if (t) { + pr_debug("md: waking up MD thread %s.\n", t->tsk->comm); +@@ -8398,9 +8397,8 @@ void md_wakeup_thread(struct md_thread __rcu *thread) + if (wq_has_sleeper(&t->wqueue)) + wake_up(&t->wqueue); + } +- rcu_read_unlock(); + } +-EXPORT_SYMBOL(md_wakeup_thread); ++EXPORT_SYMBOL(__md_wakeup_thread); + + struct md_thread *md_register_thread(void (*run) (struct md_thread *), + struct mddev *mddev, const char *name) +diff --git a/drivers/md/md.h b/drivers/md/md.h +index 1979c2d4fe89e..5d5f780b84477 100644 +--- a/drivers/md/md.h ++++ b/drivers/md/md.h +@@ -882,6 +882,12 @@ struct md_io_clone { + + #define THREAD_WAKEUP 0 + ++#define md_wakeup_thread(thread) do { \ ++ rcu_read_lock(); \ ++ __md_wakeup_thread(thread); \ ++ rcu_read_unlock(); \ ++} while (0) ++ + static inline void safe_put_page(struct page *p) + { + if (p) put_page(p); +@@ -895,7 +901,7 @@ extern struct md_thread *md_register_thread( + struct mddev *mddev, + const char *name); + extern void md_unregister_thread(struct mddev *mddev, struct md_thread __rcu **threadp); +-extern void md_wakeup_thread(struct md_thread __rcu *thread); ++extern void __md_wakeup_thread(struct md_thread __rcu *thread); + extern void md_check_recovery(struct mddev *mddev); + extern void md_reap_sync_thread(struct mddev *mddev); + extern enum sync_action md_sync_action(struct mddev *mddev); +-- +2.51.0 + diff --git a/queue-6.18/md-init-bioset-in-mddev_init.patch b/queue-6.18/md-init-bioset-in-mddev_init.patch new file mode 100644 index 0000000000..c42b26c758 --- /dev/null +++ b/queue-6.18/md-init-bioset-in-mddev_init.patch @@ -0,0 +1,180 @@ +From 97da5628cbf5da0e13ea2873bf0b03c8cc863043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 20:57:54 +0800 +Subject: md: init bioset in mddev_init + +From: Li Nan + +[ Upstream commit 381a3ce1c0ffed647c9b913e142b099c7e9d5afc ] + +IO operations may be needed before md_run(), such as updating metadata +after writing sysfs. Without bioset, this triggers a NULL pointer +dereference as below: + + BUG: kernel NULL pointer dereference, address: 0000000000000020 + Call Trace: + md_update_sb+0x658/0xe00 + new_level_store+0xc5/0x120 + md_attr_store+0xc9/0x1e0 + sysfs_kf_write+0x6f/0xa0 + kernfs_fop_write_iter+0x141/0x2a0 + vfs_write+0x1fc/0x5a0 + ksys_write+0x79/0x180 + __x64_sys_write+0x1d/0x30 + x64_sys_call+0x2818/0x2880 + do_syscall_64+0xa9/0x580 + entry_SYSCALL_64_after_hwframe+0x4b/0x53 + +Reproducer +``` + mdadm -CR /dev/md0 -l1 -n2 /dev/sd[cd] + echo inactive > /sys/block/md0/md/array_state + echo 10 > /sys/block/md0/md/new_level +``` + +mddev_init() can only be called once per mddev, no need to test if bioset +has been initialized anymore. + +Link: https://lore.kernel.org/linux-raid/20251103125757.1405796-3-linan666@huaweicloud.com +Fixes: d981ed841930 ("md: Add new_level sysfs interface") +Signed-off-by: Li Nan +Reviewed-by: Xiao Ni +Signed-off-by: Yu Kuai +Signed-off-by: Sasha Levin +--- + drivers/md/md.c | 69 +++++++++++++++++++++++-------------------------- + 1 file changed, 33 insertions(+), 36 deletions(-) + +diff --git a/drivers/md/md.c b/drivers/md/md.c +index 7b21eb1dbc533..cef5b2954ac5a 100644 +--- a/drivers/md/md.c ++++ b/drivers/md/md.c +@@ -730,6 +730,8 @@ static void mddev_clear_bitmap_ops(struct mddev *mddev) + + int mddev_init(struct mddev *mddev) + { ++ int err = 0; ++ + if (!IS_ENABLED(CONFIG_MD_BITMAP)) + mddev->bitmap_id = ID_BITMAP_NONE; + else +@@ -741,10 +743,23 @@ int mddev_init(struct mddev *mddev) + + if (percpu_ref_init(&mddev->writes_pending, no_op, + PERCPU_REF_ALLOW_REINIT, GFP_KERNEL)) { +- percpu_ref_exit(&mddev->active_io); +- return -ENOMEM; ++ err = -ENOMEM; ++ goto exit_acitve_io; + } + ++ err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); ++ if (err) ++ goto exit_writes_pending; ++ ++ err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); ++ if (err) ++ goto exit_bio_set; ++ ++ err = bioset_init(&mddev->io_clone_set, BIO_POOL_SIZE, ++ offsetof(struct md_io_clone, bio_clone), 0); ++ if (err) ++ goto exit_sync_set; ++ + /* We want to start with the refcount at zero */ + percpu_ref_put(&mddev->writes_pending); + +@@ -773,11 +788,24 @@ int mddev_init(struct mddev *mddev) + INIT_WORK(&mddev->del_work, mddev_delayed_delete); + + return 0; ++ ++exit_sync_set: ++ bioset_exit(&mddev->sync_set); ++exit_bio_set: ++ bioset_exit(&mddev->bio_set); ++exit_writes_pending: ++ percpu_ref_exit(&mddev->writes_pending); ++exit_acitve_io: ++ percpu_ref_exit(&mddev->active_io); ++ return err; + } + EXPORT_SYMBOL_GPL(mddev_init); + + void mddev_destroy(struct mddev *mddev) + { ++ bioset_exit(&mddev->bio_set); ++ bioset_exit(&mddev->sync_set); ++ bioset_exit(&mddev->io_clone_set); + percpu_ref_exit(&mddev->active_io); + percpu_ref_exit(&mddev->writes_pending); + } +@@ -6387,29 +6415,9 @@ int md_run(struct mddev *mddev) + nowait = nowait && bdev_nowait(rdev->bdev); + } + +- if (!bioset_initialized(&mddev->bio_set)) { +- err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); +- if (err) +- return err; +- } +- if (!bioset_initialized(&mddev->sync_set)) { +- err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); +- if (err) +- goto exit_bio_set; +- } +- +- if (!bioset_initialized(&mddev->io_clone_set)) { +- err = bioset_init(&mddev->io_clone_set, BIO_POOL_SIZE, +- offsetof(struct md_io_clone, bio_clone), 0); +- if (err) +- goto exit_sync_set; +- } +- + pers = get_pers(mddev->level, mddev->clevel); +- if (!pers) { +- err = -EINVAL; +- goto abort; +- } ++ if (!pers) ++ return -EINVAL; + if (mddev->level != pers->head.id) { + mddev->level = pers->head.id; + mddev->new_level = pers->head.id; +@@ -6420,8 +6428,7 @@ int md_run(struct mddev *mddev) + pers->start_reshape == NULL) { + /* This personality cannot handle reshaping... */ + put_pers(pers); +- err = -EINVAL; +- goto abort; ++ return -EINVAL; + } + + if (pers->sync_request) { +@@ -6548,12 +6555,6 @@ int md_run(struct mddev *mddev) + mddev->private = NULL; + put_pers(pers); + md_bitmap_destroy(mddev); +-abort: +- bioset_exit(&mddev->io_clone_set); +-exit_sync_set: +- bioset_exit(&mddev->sync_set); +-exit_bio_set: +- bioset_exit(&mddev->bio_set); + return err; + } + EXPORT_SYMBOL_GPL(md_run); +@@ -6778,10 +6779,6 @@ static void __md_stop(struct mddev *mddev) + mddev->private = NULL; + put_pers(pers); + clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); +- +- bioset_exit(&mddev->bio_set); +- bioset_exit(&mddev->sync_set); +- bioset_exit(&mddev->io_clone_set); + } + + void md_stop(struct mddev *mddev) +-- +2.51.0 + diff --git a/queue-6.18/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch b/queue-6.18/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch new file mode 100644 index 0000000000..1d0210703c --- /dev/null +++ b/queue-6.18/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch @@ -0,0 +1,99 @@ +From 4c65c66583a6d88d0c05e32a7765b911b9d034db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 16:55:57 +0800 +Subject: md/raid5: fix IO hang when array is broken with IO inflight + +From: Yu Kuai + +[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ] + +Following test can cause IO hang: + +mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none +sleep 5 +echo 1 > /sys/block/sda/device/delete +echo 1 > /sys/block/sdb/device/delete +echo 1 > /sys/block/sdc/device/delete +echo 1 > /sys/block/sdd/device/delete + +dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct + +Root cause: + +1) all disks removed, however all rdevs in the array is still in sync, +IO will be issued normally. + +2) IO failure from sda, and set badblocks failed, sda will be faulty +and MD_SB_CHANGING_PENDING will be set. + +3) error recovery try to recover this IO from other disks, IO will be +issued to sdb, sdc, and sdd. + +4) IO failure from sdb, and set badblocks failed again, now array is +broken and will become read-only. + +5) IO failure from sdc and sdd, however, stripe can't be handled anymore +because MD_SB_CHANGING_PENDING is set: + +handle_stripe + handle_stripe + if (test_bit MD_SB_CHANGING_PENDING) + set_bit STRIPE_HANDLE + goto finish + // skip handling failed stripe + +release_stripe + if (test_bit STRIPE_HANDLE) + list_add_tail conf->hand_list + +6) later raid5d can't handle failed stripe as well: + +raid5d + md_check_recovery + md_update_sb + if (!md_is_rdwr()) + // can't clear pending bit + return + if (test_bit MD_SB_CHANGING_PENDING) + break; + // can't handle failed stripe + +Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, +fix this problem by skip this checking for read-only array. + +Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com +Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") +Signed-off-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 24b32a0c95b40..8b5f8a12d4179 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -4956,7 +4956,8 @@ static void handle_stripe(struct stripe_head *sh) + goto finish; + + if (s.handle_bad_blocks || +- test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { ++ (md_is_rdwr(conf->mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { + set_bit(STRIPE_HANDLE, &sh->state); + goto finish; + } +@@ -6768,7 +6769,8 @@ static void raid5d(struct md_thread *thread) + int batch_size, released; + unsigned int offset; + +- if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ if (md_is_rdwr(mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + + released = release_stripe_list(conf, conf->temp_inactive_list); +-- +2.51.0 + diff --git a/queue-6.18/media-ov02c10-fix-default-vertical-flip.patch b/queue-6.18/media-ov02c10-fix-default-vertical-flip.patch new file mode 100644 index 0000000000..7b7661418b --- /dev/null +++ b/queue-6.18/media-ov02c10-fix-default-vertical-flip.patch @@ -0,0 +1,42 @@ +From 14cc4474799a595caeccdb8fdf2ca4b867cef972 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 20 Aug 2025 02:13:19 +0200 +Subject: media: ov02c10: Fix default vertical flip + +From: Sebastian Reichel + +[ Upstream commit d5ebe3f7d13d4cee3ff7e718de23564915aaf163 ] + +The driver right now defaults to setting the vertical flip bit. This +conflicts with proper handling of the rotation property defined in +ACPI or device tree, so drop the VFLIP bit. It should be handled via +V4L2_CID_VFLIP instead. + +Reported-by: Frederic Stuyk +Closes: https://lore.kernel.org/all/b6df9ae7-ea9f-4e5a-8065-5b130f534f37@runbox.com/ +Fixes: 44f89010dae0 ("media: i2c: Add Omnivision OV02C10 sensor driver") +Signed-off-by: Sebastian Reichel +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Sakari Ailus +Signed-off-by: Hans Verkuil +Signed-off-by: Sasha Levin +--- + drivers/media/i2c/ov02c10.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c +index 8c4d85dc7922e..8e22ff446b0c4 100644 +--- a/drivers/media/i2c/ov02c10.c ++++ b/drivers/media/i2c/ov02c10.c +@@ -174,7 +174,7 @@ static const struct reg_sequence sensor_1928x1092_30fps_setting[] = { + {0x3816, 0x01}, + {0x3817, 0x01}, + +- {0x3820, 0xb0}, ++ {0x3820, 0xa0}, + {0x3821, 0x00}, + {0x3822, 0x80}, + {0x3823, 0x08}, +-- +2.51.0 + diff --git a/queue-6.18/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-6.18/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..dc22901646 --- /dev/null +++ b/queue-6.18/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From 6ece90867dffbd8afa77a171ca1df86cf7d39964 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index 1f727ef60d638..8c989b74f924e 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.18/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..4bc92990bd --- /dev/null +++ b/queue-6.18/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 335472d720b3b5cc8e0a08fc77dd63dd7cbead95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index f467b00d23660..74cf208430440 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -285,6 +285,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.18/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..51279a5ca4 --- /dev/null +++ b/queue-6.18/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 25afee9ae3c2159bec30f14612a62710da5cd17b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 0e463026c5a91..5d2e5459f7444 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -229,6 +229,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch b/queue-6.18/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch new file mode 100644 index 0000000000..d4a6b92e41 --- /dev/null +++ b/queue-6.18/misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch @@ -0,0 +1,42 @@ +From 6f310e476047e12db90971c00ff6265d2722d2e4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 08:14:04 +0100 +Subject: misc: rp1: Fix an error handling path in rp1_probe() + +From: Christophe JAILLET + +[ Upstream commit 43cd4b634ef90c4e2ff75eaeb361786fa04c8874 ] + +When DT is used to get the reference of 'rp1_node', it should be released +when not needed anymore, otherwise it is leaking. + +In such a case, add the missing of_node_put() call at the end of the probe, +as already done in the error handling path. + +Fixes: 49d63971f963 ("misc: rp1: RaspberryPi RP1 misc driver") +Signed-off-by: Christophe JAILLET +Reviewed-by: Andrea della Porta +Link: https://patch.msgid.link/9bc1206de787fa86384f3e5ba0a8027947bc00ff.1762585959.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/misc/rp1/rp1_pci.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/misc/rp1/rp1_pci.c b/drivers/misc/rp1/rp1_pci.c +index 803832006ec87..a342bcc6164bb 100644 +--- a/drivers/misc/rp1/rp1_pci.c ++++ b/drivers/misc/rp1/rp1_pci.c +@@ -289,6 +289,9 @@ static int rp1_probe(struct pci_dev *pdev, const struct pci_device_id *id) + goto err_unload_overlay; + } + ++ if (skip_ovl) ++ of_node_put(rp1_node); ++ + return 0; + + err_unload_overlay: +-- +2.51.0 + diff --git a/queue-6.18/mshv-fix-create-memory-region-overlap-check.patch b/queue-6.18/mshv-fix-create-memory-region-overlap-check.patch new file mode 100644 index 0000000000..41c2b748e6 --- /dev/null +++ b/queue-6.18/mshv-fix-create-memory-region-overlap-check.patch @@ -0,0 +1,86 @@ +From 98082b2da72f8558a54c03d7947e846146e8c919 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:13:30 -0800 +Subject: mshv: Fix create memory region overlap check + +From: Nuno Das Neves + +[ Upstream commit ba9eb9b86d232854e983203dc2fb1ba18e316681 ] + +The current check is incorrect; it only checks if the beginning or end +of a region is within an existing region. This doesn't account for +userspace specifying a region that begins before and ends after an +existing region. + +Change the logic to a range intersection check against gfns and uaddrs +for each region. + +Remove mshv_partition_region_by_uaddr() as it is no longer used. + +Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Reported-by: Michael Kelley +Closes: https://lore.kernel.org/linux-hyperv/SN6PR02MB41575BE0406D3AB22E1D7DB5D4C2A@SN6PR02MB4157.namprd02.prod.outlook.com/ +Signed-off-by: Nuno Das Neves +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_root_main.c | 31 +++++++++++-------------------- + 1 file changed, 11 insertions(+), 20 deletions(-) + +diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c +index 5156b8b0a39f4..4e04bef544379 100644 +--- a/drivers/hv/mshv_root_main.c ++++ b/drivers/hv/mshv_root_main.c +@@ -1174,21 +1174,6 @@ mshv_partition_region_by_gfn(struct mshv_partition *partition, u64 gfn) + return NULL; + } + +-static struct mshv_mem_region * +-mshv_partition_region_by_uaddr(struct mshv_partition *partition, u64 uaddr) +-{ +- struct mshv_mem_region *region; +- +- hlist_for_each_entry(region, &partition->pt_mem_regions, hnode) { +- if (uaddr >= region->start_uaddr && +- uaddr < region->start_uaddr + +- (region->nr_pages << HV_HYP_PAGE_SHIFT)) +- return region; +- } +- +- return NULL; +-} +- + /* + * NB: caller checks and makes sure mem->size is page aligned + * Returns: 0 with regionpp updated on success, or -errno +@@ -1198,15 +1183,21 @@ static int mshv_partition_create_region(struct mshv_partition *partition, + struct mshv_mem_region **regionpp, + bool is_mmio) + { +- struct mshv_mem_region *region; ++ struct mshv_mem_region *region, *rg; + u64 nr_pages = HVPFN_DOWN(mem->size); + + /* Reject overlapping regions */ +- if (mshv_partition_region_by_gfn(partition, mem->guest_pfn) || +- mshv_partition_region_by_gfn(partition, mem->guest_pfn + nr_pages - 1) || +- mshv_partition_region_by_uaddr(partition, mem->userspace_addr) || +- mshv_partition_region_by_uaddr(partition, mem->userspace_addr + mem->size - 1)) ++ hlist_for_each_entry(rg, &partition->pt_mem_regions, hnode) { ++ u64 rg_size = rg->nr_pages << HV_HYP_PAGE_SHIFT; ++ ++ if ((mem->guest_pfn + nr_pages <= rg->start_gfn || ++ rg->start_gfn + rg->nr_pages <= mem->guest_pfn) && ++ (mem->userspace_addr + mem->size <= rg->start_uaddr || ++ rg->start_uaddr + rg_size <= mem->userspace_addr)) ++ continue; ++ + return -EEXIST; ++ } + + region = vzalloc(sizeof(*region) + sizeof(struct page *) * nr_pages); + if (!region) +-- +2.51.0 + diff --git a/queue-6.18/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch b/queue-6.18/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch new file mode 100644 index 0000000000..66191f8b61 --- /dev/null +++ b/queue-6.18/mshv-fix-deposit-memory-in-mshv_root_hvcall.patch @@ -0,0 +1,171 @@ +From ef75280612c7c1cd7db830ae2734e60f50fcc530 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 11:58:17 -0700 +Subject: mshv: Fix deposit memory in MSHV_ROOT_HVCALL + +From: Nuno Das Neves + +[ Upstream commit 4cc1aa469cd6b714adc958547a4866247bfd60a9 ] + +When the MSHV_ROOT_HVCALL ioctl is executing a hypercall, and gets +HV_STATUS_INSUFFICIENT_MEMORY, it deposits memory and then returns +-EAGAIN to userspace. The expectation is that the VMM will retry. + +However, some VMM code in the wild doesn't do this and simply fails. +Rather than force the VMM to retry, change the ioctl to deposit +memory on demand and immediately retry the hypercall as is done with +all the other hypercall helper functions. + +In addition to making the ioctl easier to use, removing the need for +multiple syscalls improves performance. + +There is a complication: unlike the other hypercall helper functions, +in MSHV_ROOT_HVCALL the input is opaque to the kernel. This is +problematic for rep hypercalls, because the next part of the input +list can't be copied on each loop after depositing pages (this was +the original reason for returning -EAGAIN in this case). + +Introduce hv_do_rep_hypercall_ex(), which adds a 'rep_start' +parameter. This solves the issue, allowing the deposit loop in +MSHV_ROOT_HVCALL to restart a rep hypercall after depositing pages +partway through. + +Fixes: 621191d709b1 ("Drivers: hv: Introduce mshv_root module to expose /dev/mshv to VMMs") +Signed-off-by: Nuno Das Neves +Reviewed-by: Michael Kelley +Signed-off-by: Wei Liu +Signed-off-by: Sasha Levin +--- + drivers/hv/mshv_root_main.c | 58 ++++++++++++++++++---------------- + include/asm-generic/mshyperv.h | 17 ++++++++-- + 2 files changed, 44 insertions(+), 31 deletions(-) + +diff --git a/drivers/hv/mshv_root_main.c b/drivers/hv/mshv_root_main.c +index e3b2bd417c464..5156b8b0a39f4 100644 +--- a/drivers/hv/mshv_root_main.c ++++ b/drivers/hv/mshv_root_main.c +@@ -159,6 +159,7 @@ static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, + unsigned int pages_order; + void *input_pg = NULL; + void *output_pg = NULL; ++ u16 reps_completed; + + if (copy_from_user(&args, user_args, sizeof(args))) + return -EFAULT; +@@ -210,41 +211,42 @@ static int mshv_ioctl_passthru_hvcall(struct mshv_partition *partition, + */ + *(u64 *)input_pg = partition->pt_id; + +- if (args.reps) +- status = hv_do_rep_hypercall(args.code, args.reps, 0, +- input_pg, output_pg); +- else +- status = hv_do_hypercall(args.code, input_pg, output_pg); +- +- if (hv_result(status) == HV_STATUS_CALL_PENDING) { +- if (is_async) { +- mshv_async_hvcall_handler(partition, &status); +- } else { /* Paranoia check. This shouldn't happen! */ +- ret = -EBADFD; +- goto free_pages_out; ++ reps_completed = 0; ++ do { ++ if (args.reps) { ++ status = hv_do_rep_hypercall_ex(args.code, args.reps, ++ 0, reps_completed, ++ input_pg, output_pg); ++ reps_completed = hv_repcomp(status); ++ } else { ++ status = hv_do_hypercall(args.code, input_pg, output_pg); + } +- } + +- if (hv_result(status) == HV_STATUS_INSUFFICIENT_MEMORY) { +- ret = hv_call_deposit_pages(NUMA_NO_NODE, partition->pt_id, 1); +- if (!ret) +- ret = -EAGAIN; +- } else if (!hv_result_success(status)) { +- ret = hv_result_to_errno(status); +- } ++ if (hv_result(status) == HV_STATUS_CALL_PENDING) { ++ if (is_async) { ++ mshv_async_hvcall_handler(partition, &status); ++ } else { /* Paranoia check. This shouldn't happen! */ ++ ret = -EBADFD; ++ goto free_pages_out; ++ } ++ } ++ ++ if (hv_result_success(status)) ++ break; ++ ++ if (hv_result(status) != HV_STATUS_INSUFFICIENT_MEMORY) ++ ret = hv_result_to_errno(status); ++ else ++ ret = hv_call_deposit_pages(NUMA_NO_NODE, ++ partition->pt_id, 1); ++ } while (!ret); + +- /* +- * Always return the status and output data regardless of result. +- * The VMM may need it to determine how to proceed. E.g. the status may +- * contain the number of reps completed if a rep hypercall partially +- * succeeded. +- */ + args.status = hv_result(status); +- args.reps = args.reps ? hv_repcomp(status) : 0; ++ args.reps = reps_completed; + if (copy_to_user(user_args, &args, sizeof(args))) + ret = -EFAULT; + +- if (output_pg && ++ if (!ret && output_pg && + copy_to_user((void __user *)args.out_ptr, output_pg, args.out_sz)) + ret = -EFAULT; + +diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h +index 64ba6bc807d98..b89c7e3a20474 100644 +--- a/include/asm-generic/mshyperv.h ++++ b/include/asm-generic/mshyperv.h +@@ -124,10 +124,12 @@ static inline unsigned int hv_repcomp(u64 status) + + /* + * Rep hypercalls. Callers of this functions are supposed to ensure that +- * rep_count and varhead_size comply with Hyper-V hypercall definition. ++ * rep_count, varhead_size, and rep_start comply with Hyper-V hypercall ++ * definition. + */ +-static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, +- void *input, void *output) ++static inline u64 hv_do_rep_hypercall_ex(u16 code, u16 rep_count, ++ u16 varhead_size, u16 rep_start, ++ void *input, void *output) + { + u64 control = code; + u64 status; +@@ -135,6 +137,7 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + + control |= (u64)varhead_size << HV_HYPERCALL_VARHEAD_OFFSET; + control |= (u64)rep_count << HV_HYPERCALL_REP_COMP_OFFSET; ++ control |= (u64)rep_start << HV_HYPERCALL_REP_START_OFFSET; + + do { + status = hv_do_hypercall(control, input, output); +@@ -152,6 +155,14 @@ static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, + return status; + } + ++/* For the typical case where rep_start is 0 */ ++static inline u64 hv_do_rep_hypercall(u16 code, u16 rep_count, u16 varhead_size, ++ void *input, void *output) ++{ ++ return hv_do_rep_hypercall_ex(code, rep_count, varhead_size, 0, ++ input, output); ++} ++ + /* Generate the guest OS identifier as described in the Hyper-V TLFS */ + static inline u64 hv_generate_guest_id(u64 kernel_version) + { +-- +2.51.0 + diff --git a/queue-6.18/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-6.18/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..5cf49cf99e --- /dev/null +++ b/queue-6.18/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From fba36fb95555e7e7e8b3a52ffc23240a879f3b13 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index 4064e193d4dec..08ee2e861c4e2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -874,8 +874,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-6.18/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-6.18/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..30cba3f0a2 --- /dev/null +++ b/queue-6.18/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From ce21f54a0226753dcfbe5272ec1ae723a5eae87f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index 290fd0119e984..cd37d58abacb7 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-6.18/mtd-nand-relax-ecc-parameter-validation-check.patch b/queue-6.18/mtd-nand-relax-ecc-parameter-validation-check.patch new file mode 100644 index 0000000000..b9c8f8550a --- /dev/null +++ b/queue-6.18/mtd-nand-relax-ecc-parameter-validation-check.patch @@ -0,0 +1,53 @@ +From 5256269813b1a5124e02a2f6614db9528508c3ef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:42 +1300 +Subject: mtd: nand: relax ECC parameter validation check + +From: Aryan Srivastava + +[ Upstream commit 050553c683f21eebd7d1020df9b2ec852e2a9e4e ] + +Due to the custom handling and layouts of certain nand controllers this +validity check will always fail for certain layouts. The check +inherently depends on even chunk sizing and this is not always the +case. + +Modify the check to only print a warning, instead of failing to +init the attached NAND. This allows various 8 bit and 12 ECC strength +layouts to be used. + +Fixes: 68c18dae6888 ("mtd: rawnand: marvell: add missing layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/nand_base.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index c7d9501f646b3..ad6d66309597b 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -6338,11 +6338,14 @@ static int nand_scan_tail(struct nand_chip *chip) + ecc->steps = mtd->writesize / ecc->size; + if (!base->ecc.ctx.nsteps) + base->ecc.ctx.nsteps = ecc->steps; +- if (ecc->steps * ecc->size != mtd->writesize) { +- WARN(1, "Invalid ECC parameters\n"); +- ret = -EINVAL; +- goto err_nand_manuf_cleanup; +- } ++ ++ /* ++ * Validity check: Warn if ECC parameters are not compatible with page size. ++ * Due to the custom handling of ECC blocks in certain controllers the check ++ * may result in an expected failure. ++ */ ++ if (ecc->steps * ecc->size != mtd->writesize) ++ pr_warn("ECC parameters may be invalid in reference to underlying NAND chip\n"); + + if (!ecc->total) { + ecc->total = ecc->steps * ecc->bytes; +-- +2.51.0 + diff --git a/queue-6.18/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch b/queue-6.18/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch new file mode 100644 index 0000000000..8fdd37aa27 --- /dev/null +++ b/queue-6.18/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch @@ -0,0 +1,50 @@ +From 9f2b24275cf271476156db6fe5740b8b9b37e043 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 17:47:47 +0800 +Subject: mtd: rawnand: lpc32xx_slc: fix GPIO descriptor leak on probe error + and remove + +From: Haotian Zhang + +[ Upstream commit cdf44f1add4ec9ee80569d5a43e6e9bba0d74c7a ] + +The driver calls gpiod_get_optional() in the probe function but +never calls gpiod_put() in the remove function or in the probe +error path. This leads to a GPIO descriptor resource leak. +The lpc32xx_mlc.c driver in the same directory handles this +correctly by calling gpiod_put() on both paths. + +Add gpiod_put() in the remove function and in the probe error path +to fix the resource leak. + +Fixes: 6b923db2867c ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") +Signed-off-by: Haotian Zhang +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/lpc32xx_slc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c +index b54d76547ffb2..fea3705a21386 100644 +--- a/drivers/mtd/nand/raw/lpc32xx_slc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c +@@ -937,6 +937,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) + dma_release_channel(host->dma_chan); + enable_wp: + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + + return res; + } +@@ -962,6 +963,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev) + writel(tmp, SLC_CTRL(host->io_base)); + + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + } + + static int lpc32xx_nand_resume(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.18/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch b/queue-6.18/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch new file mode 100644 index 0000000000..bab0b4859a --- /dev/null +++ b/queue-6.18/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch @@ -0,0 +1,45 @@ +From 7ce0afdbf2ce72ab7cb096b2d0a04910f1cdfdd1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 00:35:51 +0800 +Subject: mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors + +From: Haotian Zhang + +[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ] + +devm_pm_runtime_enable() can fail due to memory allocation failures. +The current code ignores its return value and proceeds with +pm_runtime_resume_and_get(), which may operate on incorrectly +initialized runtime PM state. + +Check the return value of devm_pm_runtime_enable() and return the +error code if it fails. + +Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c +index ac8c1b80d7be9..201dd62b99905 100644 +--- a/drivers/mtd/nand/raw/renesas-nand-controller.c ++++ b/drivers/mtd/nand/raw/renesas-nand-controller.c +@@ -1336,7 +1336,10 @@ static int rnandc_probe(struct platform_device *pdev) + if (IS_ERR(rnandc->regs)) + return PTR_ERR(rnandc->regs); + +- devm_pm_runtime_enable(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +-- +2.51.0 + diff --git a/queue-6.18/nbd-defer-config-put-in-recv_work.patch b/queue-6.18/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..753d0faf8d --- /dev/null +++ b/queue-6.18/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From b51d0a2b3667e38793c48bb7208fa6853da3c156 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index a853c65ac65df..215fc18115b78 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -1024,9 +1024,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-6.18/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-6.18/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..af8c1708b2 --- /dev/null +++ b/queue-6.18/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From 1d6c661b8e2c125cd58b04904f939306c1af5dc6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 215fc18115b78..a05ff68e58d06 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2241,12 +2241,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch b/queue-6.18/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch new file mode 100644 index 0000000000..126a103e3a --- /dev/null +++ b/queue-6.18/net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch @@ -0,0 +1,235 @@ +From f7ca9d25ba45ac084e1101496c0c93928910c9a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:48 +0100 +Subject: net: dsa: b53: add support for 5389/5397/5398 ARL entry format + +From: Jonas Gorski + +[ Upstream commit 300f78e8b6b7be17c2c78afeded75be68acb1aa7 ] + +BCM5389, BCM5397 and BCM5398 use a different ARL entry format with just +a 16 bit fwdentry register, as well as different search control and data +offsets. + +So add appropriate ops for them and switch those chips to use them. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-8-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 53 ++++++++++++++++++++++++++++++-- + drivers/net/dsa/b53/b53_priv.h | 26 ++++++++++++++++ + drivers/net/dsa/b53/b53_regs.h | 13 ++++++++ + 3 files changed, 89 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 50ed9b7157197..dedbd53412871 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1850,6 +1850,31 @@ static void b53_arl_write_entry_25(struct b53_device *dev, + mac_vid); + } + ++static void b53_arl_read_entry_89(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ u64 mac_vid; ++ u16 fwd_entry; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry); ++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry); ++} ++ ++static void b53_arl_write_entry_89(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_arl_from_entry_89(&mac_vid, &fwd_entry, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, ++ B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid); ++ b53_write16(dev, B53_ARLIO_PAGE, ++ B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); ++} ++ + static void b53_arl_read_entry_95(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +@@ -2017,6 +2042,8 @@ static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +@@ -2029,6 +2056,8 @@ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +@@ -2074,6 +2103,18 @@ static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, + b53_arl_to_entry_25(ent, mac_vid); + } + ++static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u16 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_89, ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_89, &fwd_entry); ++ b53_arl_to_entry_89(ent, mac_vid, fwd_entry); ++} ++ + static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2664,6 +2705,12 @@ static const struct b53_arl_ops b53_arl_ops_65 = { + .arl_search_read = b53_arl_search_read_65, + }; + ++static const struct b53_arl_ops b53_arl_ops_89 = { ++ .arl_read_entry = b53_arl_read_entry_89, ++ .arl_write_entry = b53_arl_write_entry_89, ++ .arl_search_read = b53_arl_search_read_89, ++}; ++ + static const struct b53_arl_ops b53_arl_ops_95 = { + .arl_read_entry = b53_arl_read_entry_95, + .arl_write_entry = b53_arl_write_entry_95, +@@ -2728,7 +2775,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM5395_DEVICE_ID, +@@ -2756,7 +2803,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM5398_DEVICE_ID, +@@ -2770,7 +2817,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_89, + }, + { + .chip_id = BCM53101_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index c6e2d5e41c758..127ce7f6b16ba 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -353,6 +353,18 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + ++static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent, ++ u64 mac_vid, u16 fwd_entry) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ ent->port = fwd_entry & ARLTBL_DATA_PORT_ID_MASK_89; ++ ent->is_valid = !!(fwd_entry & ARLTBL_VALID_89); ++ ent->is_age = !!(fwd_entry & ARLTBL_AGE_89); ++ ent->is_static = !!(fwd_entry & ARLTBL_STATIC_89); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = mac_vid >> ARLTBL_VID_S; ++} ++ + static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, + const struct b53_arl_entry *ent) + { +@@ -383,6 +395,20 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + *mac_vid |= ARLTBL_AGE_25; + } + ++static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, ++ const struct b53_arl_entry *ent) ++{ ++ *mac_vid = ether_addr_to_u64(ent->mac); ++ *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK) << ARLTBL_VID_S; ++ *fwd_entry = ent->port & ARLTBL_DATA_PORT_ID_MASK_89; ++ if (ent->is_valid) ++ *fwd_entry |= ARLTBL_VALID_89; ++ if (ent->is_static) ++ *fwd_entry |= ARLTBL_STATIC_89; ++ if (ent->is_age) ++ *fwd_entry |= ARLTBL_AGE_89; ++} ++ + static inline void b53_arl_read_entry(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index 8ce1ce72e9385..d9026cf865549 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -342,12 +342,20 @@ + #define ARLTBL_STATIC BIT(15) + #define ARLTBL_VALID BIT(16) + ++/* BCM5389 ARL Table Data Entry N Register format (16 bit) */ ++#define ARLTBL_DATA_PORT_ID_MASK_89 GENMASK(8, 0) ++#define ARLTBL_TC_MASK_89 GENMASK(12, 10) ++#define ARLTBL_AGE_89 BIT(13) ++#define ARLTBL_STATIC_89 BIT(14) ++#define ARLTBL_VALID_89 BIT(15) ++ + /* Maximum number of bin entries in the ARL for all switches */ + #define B53_ARLTBL_MAX_BIN_ENTRIES 4 + + /* ARL Search Control Register (8 bit) */ + #define B53_ARL_SRCH_CTL 0x50 + #define B53_ARL_SRCH_CTL_25 0x20 ++#define B53_ARL_SRCH_CTL_89 0x30 + #define ARL_SRCH_VLID BIT(0) + #define ARL_SRCH_STDN BIT(7) + +@@ -355,10 +363,12 @@ + #define B53_ARL_SRCH_ADDR 0x51 + #define B53_ARL_SRCH_ADDR_25 0x22 + #define B53_ARL_SRCH_ADDR_65 0x24 ++#define B53_ARL_SRCH_ADDR_89 0x31 + #define ARL_ADDR_MASK GENMASK(14, 0) + + /* ARL Search MAC/VID Result (64 bit) */ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 ++#define B53_ARL_SRCH_RSLT_MACVID_89 0x33 + + /* Single register search result on 5325 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +@@ -368,6 +378,9 @@ + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 + ++/* BCM5389 ARL Search Data Result (16 bit) */ ++#define B53_ARL_SRCH_RSLT_89 0x3b ++ + #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) + #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) + +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch b/queue-6.18/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch new file mode 100644 index 0000000000..47e56d9581 --- /dev/null +++ b/queue-6.18/net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch @@ -0,0 +1,192 @@ +From b26a651fa3acb714dec1eb367ea13dc46eaf841b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:49 +0100 +Subject: net: dsa: b53: add support for bcm63xx ARL entry format + +From: Jonas Gorski + +[ Upstream commit 2b3013ac03028a2364d8779719bb6bfbc0212435 ] + +The ARL registers of BCM63XX embedded switches are somewhat unique. The +normal ARL table access registers have the same format as BCM5389, but +the ARL search registers differ: + +* SRCH_CTL is at the same offset of BCM5389, but 16 bits wide. It does + not have more fields, just needs to be accessed by a 16 bit read. +* SRCH_RSLT_MACVID and SRCH_RSLT are aligned to 32 bit, and have shifted + offsets. +* SRCH_RSLT has a different format than the normal ARL data entry + register. +* There is only one set of ENTRY_N registers, implying a 1 bin layout. + +So add appropriate ops for bcm63xx and let it use it. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-9-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 3b08863469aa ("net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 44 +++++++++++++++++++++++++++----- + drivers/net/dsa/b53/b53_priv.h | 15 +++++++++++ + drivers/net/dsa/b53/b53_regs.h | 9 +++++++ + 3 files changed, 61 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 68e9162087ab4..db1ed8c9c536e 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2042,12 +2042,20 @@ static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; +- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) || ++ is63xx(dev)) + offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +- b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++ if (is63xx(dev)) { ++ u16 val16; ++ ++ b53_read16(dev, B53_ARLIO_PAGE, offset, &val16); ++ *val = val16 & 0xff; ++ } else { ++ b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++ } + } + + static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) +@@ -2056,12 +2064,16 @@ static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; +- else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev)) ++ else if (dev->chip_id == BCM5389_DEVICE_ID || is5397_98(dev) || ++ is63xx(dev)) + offset = B53_ARL_SRCH_CTL_89; + else + offset = B53_ARL_SRCH_CTL; + +- b53_write8(dev, B53_ARLIO_PAGE, offset, val); ++ if (is63xx(dev)) ++ b53_write16(dev, B53_ARLIO_PAGE, offset, val); ++ else ++ b53_write8(dev, B53_ARLIO_PAGE, offset, val); + } + + static int b53_arl_search_wait(struct b53_device *dev) +@@ -2105,6 +2117,18 @@ static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, + b53_arl_to_entry_89(ent, mac_vid, fwd_entry); + } + ++static void b53_arl_search_read_63xx(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u16 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_MACVID_63XX, ++ &mac_vid); ++ b53_read16(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_63XX, &fwd_entry); ++ b53_arl_search_to_entry_63xx(ent, mac_vid, fwd_entry); ++} ++ + static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2695,6 +2719,12 @@ static const struct b53_arl_ops b53_arl_ops_89 = { + .arl_search_read = b53_arl_search_read_89, + }; + ++static const struct b53_arl_ops b53_arl_ops_63xx = { ++ .arl_read_entry = b53_arl_read_entry_89, ++ .arl_write_entry = b53_arl_write_entry_89, ++ .arl_search_read = b53_arl_search_read_63xx, ++}; ++ + static const struct b53_arl_ops b53_arl_ops_95 = { + .arl_read_entry = b53_arl_read_entry_95, + .arl_write_entry = b53_arl_write_entry_95, +@@ -2864,14 +2894,14 @@ static const struct b53_chip_data b53_switch_chips[] = { + .dev_name = "BCM63xx", + .vlans = 4096, + .enabled_ports = 0, /* pdata must provide them */ +- .arl_bins = 4, +- .arl_buckets = 1024, ++ .arl_bins = 1, ++ .arl_buckets = 4096, + .imp_port = 8, + .vta_regs = B53_VTA_REGS_63XX, + .duplex_reg = B53_DUPLEX_STAT_63XX, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, +- .arl_ops = &b53_arl_ops_95, ++ .arl_ops = &b53_arl_ops_63xx, + }, + { + .chip_id = BCM53010_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 80e7dd6169b47..ae2c615c088ed 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -414,6 +414,21 @@ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE_89; + } + ++static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent, ++ u64 mac_vid, u16 fwd_entry) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = mac_vid >> ARLTBL_VID_S; ++ ++ ent->port = fwd_entry & ARL_SRST_PORT_ID_MASK_63XX; ++ ent->port >>= 1; ++ ++ ent->is_age = !!(fwd_entry & ARL_SRST_AGE_63XX); ++ ent->is_static = !!(fwd_entry & ARL_SRST_STATIC_63XX); ++ ent->is_valid = 1; ++} ++ + static inline void b53_arl_read_entry(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index f2a3696d122fa..fcedd5fb00337 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -364,11 +364,13 @@ + #define B53_ARL_SRCH_ADDR_25 0x22 + #define B53_ARL_SRCH_ADDR_65 0x24 + #define B53_ARL_SRCH_ADDR_89 0x31 ++#define B53_ARL_SRCH_ADDR_63XX 0x32 + #define ARL_ADDR_MASK GENMASK(14, 0) + + /* ARL Search MAC/VID Result (64 bit) */ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 + #define B53_ARL_SRCH_RSLT_MACVID_89 0x33 ++#define B53_ARL_SRCH_RSLT_MACVID_63XX 0x34 + + /* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +@@ -382,6 +384,13 @@ + #define B53_ARL_SRCH_RSTL_MACVID(x) (B53_ARL_SRCH_RSTL_0_MACVID + ((x) * 0x10)) + #define B53_ARL_SRCH_RSTL(x) (B53_ARL_SRCH_RSTL_0 + ((x) * 0x10)) + ++/* 63XX ARL Search Data Result (16 bit) */ ++#define B53_ARL_SRCH_RSLT_63XX 0x3c ++#define ARL_SRST_PORT_ID_MASK_63XX GENMASK(9, 1) ++#define ARL_SRST_TC_MASK_63XX GENMASK(13, 11) ++#define ARL_SRST_AGE_63XX BIT(14) ++#define ARL_SRST_STATIC_63XX BIT(15) ++ + /************************************************************************* + * IEEE 802.1X Registers + *************************************************************************/ +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch b/queue-6.18/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch new file mode 100644 index 0000000000..aa946a2718 --- /dev/null +++ b/queue-6.18/net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch @@ -0,0 +1,95 @@ +From 1c26908f96f3375ae7fbac8d502e06dcb2848395 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:42 +0100 +Subject: net: dsa: b53: b53_arl_read{,25}(): use the entry for comparision + +From: Jonas Gorski + +[ Upstream commit a6e4fd38bf2f2e2363b61c27f4e6c49b14e4bb07 ] + +Align the b53_arl_read{,25}() functions by consistently using the +parsed arl entry instead of parsing the raw registers again. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-2-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 22 ++++++++++------------ + 1 file changed, 10 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index a09ed32dccc07..4d8de90fb4ab8 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1830,7 +1830,7 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + return b53_arl_op_wait(dev); + } + +-static int b53_arl_read(struct b53_device *dev, u64 mac, ++static int b53_arl_read(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +@@ -1854,14 +1854,13 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, + B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); + b53_arl_to_entry(ent, mac_vid, fwd_entry); + +- if (!(fwd_entry & ARLTBL_VALID)) { ++ if (!ent->is_valid) { + set_bit(i, free_bins); + continue; + } +- if ((mac_vid & ARLTBL_MAC_MASK) != mac) ++ if (!ether_addr_equal(ent->mac, mac)) + continue; +- if (dev->vlan_enabled && +- ((mac_vid >> ARLTBL_VID_S) & ARLTBL_VID_MASK) != vid) ++ if (dev->vlan_enabled && ent->vid != vid) + continue; + *idx = i; + return 0; +@@ -1871,7 +1870,7 @@ static int b53_arl_read(struct b53_device *dev, u64 mac, + return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; + } + +-static int b53_arl_read_25(struct b53_device *dev, u64 mac, ++static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +@@ -1893,14 +1892,13 @@ static int b53_arl_read_25(struct b53_device *dev, u64 mac, + + b53_arl_to_entry_25(ent, mac_vid); + +- if (!(mac_vid & ARLTBL_VALID_25)) { ++ if (!ent->is_valid) { + set_bit(i, free_bins); + continue; + } +- if ((mac_vid & ARLTBL_MAC_MASK) != mac) ++ if (!ether_addr_equal(ent->mac, mac)) + continue; +- if (dev->vlan_enabled && +- ((mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25) != vid) ++ if (dev->vlan_enabled && ent->vid != vid) + continue; + *idx = i; + return 0; +@@ -1937,9 +1935,9 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + return ret; + + if (is5325(dev) || is5365(dev)) +- ret = b53_arl_read_25(dev, mac, vid, &ent, &idx); ++ ret = b53_arl_read_25(dev, addr, vid, &ent, &idx); + else +- ret = b53_arl_read(dev, mac, vid, &ent, &idx); ++ ret = b53_arl_read(dev, addr, vid, &ent, &idx); + + /* If this is a read, just finish now */ + if (op) +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch b/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch new file mode 100644 index 0000000000..78014888f2 --- /dev/null +++ b/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch @@ -0,0 +1,134 @@ +From a6eaa0e3bda4d77e31b5080ebdc6a9ddeed5164a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:23 +0100 +Subject: net: dsa: b53: fix BCM5325/65 ARL entry multicast port masks + +From: Jonas Gorski + +[ Upstream commit 3b08863469aa6028ac7c3120966f4e2f6051cf6b ] + +We currently use the mask 0xf for writing and reading b53_entry::port, +but this is only correct for unicast ARL entries. Multicast ARL entries +use a bitmask, and 0xf is not enough space for ports > 3, which includes +the CPU port. + +So extend the mask accordingly to also fit port 4 (bit 4) and MII (bit +5). According to the datasheet the multicast port mask is [60:48], +making it 12 bit wide, but bits 60-55 are reserved anyway, and collide +with the priority field at [60:59], so I am not sure if this is valid. +Therefore leave it at the actual used range, [53:48]. + +The ARL search result register differs a bit, and there the mask is only +[52:48], so only spanning the user ports. The MII port bit is +contained in the Search Result Extension register. So create a separate +search result parse function that properly handles this. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-6-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 4 +++- + drivers/net/dsa/b53/b53_priv.h | 25 +++++++++++++++++++++---- + drivers/net/dsa/b53/b53_regs.h | 8 +++++++- + 3 files changed, 31 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index db1ed8c9c536e..5544e8e9c6446 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2099,10 +2099,12 @@ static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { + u64 mac_vid; ++ u8 ext; + ++ b53_read8(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSLT_EXT_25, &ext); + b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, + &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); ++ b53_arl_search_to_entry_25(ent, mac_vid, ext); + } + + static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index ae2c615c088ed..f4afbfcc345e6 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -348,8 +348,8 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & +- ARLTBL_DATA_PORT_ID_MASK_25; ++ ent->port = (mac_vid & ARLTBL_DATA_PORT_ID_MASK_25) >> ++ ARLTBL_DATA_PORT_ID_S_25; + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + ent->port = B53_CPU_PORT_25; + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; +@@ -388,8 +388,8 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) + *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; + else +- *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << +- ARLTBL_DATA_PORT_ID_S_25; ++ *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) & ++ ARLTBL_DATA_PORT_ID_MASK_25; + *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << + ARLTBL_VID_S_65; + if (ent->is_valid) +@@ -414,6 +414,23 @@ static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE_89; + } + ++static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent, ++ u64 mac_vid, u8 ext) ++{ ++ memset(ent, 0, sizeof(*ent)); ++ ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); ++ ent->is_age = !!(mac_vid & ARLTBL_AGE_25); ++ ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); ++ u64_to_ether_addr(mac_vid, ent->mac); ++ ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >> ++ ARL_SRCH_RSLT_PORT_ID_S_25; ++ if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII)) ++ ent->port |= BIT(B53_CPU_PORT_25); ++ else if (!is_multicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ++ ent->port = B53_CPU_PORT_25; ++} ++ + static inline void b53_arl_search_to_entry_63xx(struct b53_arl_entry *ent, + u64 mac_vid, u16 fwd_entry) + { +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index fcedd5fb00337..e0379e70900b7 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -328,7 +328,7 @@ + #define ARLTBL_VID_MASK_25 0xff + #define ARLTBL_VID_MASK 0xfff + #define ARLTBL_DATA_PORT_ID_S_25 48 +-#define ARLTBL_DATA_PORT_ID_MASK_25 0xf ++#define ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48) + #define ARLTBL_VID_S_65 53 + #define ARLTBL_AGE_25 BIT_ULL(61) + #define ARLTBL_STATIC_25 BIT_ULL(62) +@@ -374,6 +374,12 @@ + + /* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 ++#define ARL_SRCH_RSLT_PORT_ID_S_25 48 ++#define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48) ++ ++/* BCM5325/5365 Search result extend register (8 bit) */ ++#define B53_ARL_SRCH_RSLT_EXT_25 0x2c ++#define ARL_SRCH_RSLT_EXT_MC_MII BIT(2) + + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch b/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch new file mode 100644 index 0000000000..df5c5c2db7 --- /dev/null +++ b/queue-6.18/net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch @@ -0,0 +1,154 @@ +From dd9403bf775aa4e969f5433a2b2caedd429acc04 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:24 +0100 +Subject: net: dsa: b53: fix BCM5325/65 ARL entry VIDs + +From: Jonas Gorski + +[ Upstream commit d39514e6a2d14f57830d649e2bf03b49612c2f73 ] + +BCM5325/65's ARL entry registers do not contain the VID, only the search +result register does. ARL entries have a separate VID entry register for +the index into the VLAN table. + +So make ARL entry accessors use the VID entry registers instead, and +move the VLAN ID field definition to the search register definition. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-7-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 9 +++++++-- + drivers/net/dsa/b53/b53_priv.h | 12 ++++++------ + drivers/net/dsa/b53/b53_regs.h | 7 +++++-- + 3 files changed, 18 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 5544e8e9c6446..62cafced758e7 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1833,19 +1833,24 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + static void b53_arl_read_entry_25(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { ++ u8 vid_entry; + u64 mac_vid; + ++ b53_read8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), ++ &vid_entry); + b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), + &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid, vid_entry); + } + + static void b53_arl_write_entry_25(struct b53_device *dev, + const struct b53_arl_entry *ent, u8 idx) + { ++ u8 vid_entry; + u64 mac_vid; + +- b53_arl_from_entry_25(&mac_vid, ent); ++ b53_arl_from_entry_25(&mac_vid, &vid_entry, ent); ++ b53_write8(dev, B53_ARLIO_PAGE, B53_ARLTBL_VID_ENTRY_25(idx), vid_entry); + b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), + mac_vid); + } +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index f4afbfcc345e6..bd6849e5bb939 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -341,7 +341,7 @@ static inline void b53_arl_to_entry(struct b53_arl_entry *ent, + } + + static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, +- u64 mac_vid) ++ u64 mac_vid, u8 vid_entry) + { + memset(ent, 0, sizeof(*ent)); + ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); +@@ -352,7 +352,7 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ARLTBL_DATA_PORT_ID_S_25; + if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) + ent->port = B53_CPU_PORT_25; +- ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->vid = vid_entry; + } + + static inline void b53_arl_to_entry_89(struct b53_arl_entry *ent, +@@ -381,7 +381,7 @@ static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, + *fwd_entry |= ARLTBL_AGE; + } + +-static inline void b53_arl_from_entry_25(u64 *mac_vid, ++static inline void b53_arl_from_entry_25(u64 *mac_vid, u8 *vid_entry, + const struct b53_arl_entry *ent) + { + *mac_vid = ether_addr_to_u64(ent->mac); +@@ -390,14 +390,13 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + else + *mac_vid |= ((u64)ent->port << ARLTBL_DATA_PORT_ID_S_25) & + ARLTBL_DATA_PORT_ID_MASK_25; +- *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << +- ARLTBL_VID_S_65; + if (ent->is_valid) + *mac_vid |= ARLTBL_VALID_25; + if (ent->is_static) + *mac_vid |= ARLTBL_STATIC_25; + if (ent->is_age) + *mac_vid |= ARLTBL_AGE_25; ++ *vid_entry = ent->vid; + } + + static inline void b53_arl_from_entry_89(u64 *mac_vid, u32 *fwd_entry, +@@ -422,7 +421,8 @@ static inline void b53_arl_search_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; ++ ent->vid = (mac_vid & ARL_SRCH_RSLT_VID_MASK_25) >> ++ ARL_SRCH_RSLT_VID_S_25; + ent->port = (mac_vid & ARL_SRCH_RSLT_PORT_ID_MASK_25) >> + ARL_SRCH_RSLT_PORT_ID_S_25; + if (is_multicast_ether_addr(ent->mac) && (ext & ARL_SRCH_RSLT_EXT_MC_MII)) +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index e0379e70900b7..b6fe7d207a2c1 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -325,11 +325,9 @@ + #define B53_ARLTBL_MAC_VID_ENTRY(n) ((0x10 * (n)) + 0x10) + #define ARLTBL_MAC_MASK 0xffffffffffffULL + #define ARLTBL_VID_S 48 +-#define ARLTBL_VID_MASK_25 0xff + #define ARLTBL_VID_MASK 0xfff + #define ARLTBL_DATA_PORT_ID_S_25 48 + #define ARLTBL_DATA_PORT_ID_MASK_25 GENMASK_ULL(53, 48) +-#define ARLTBL_VID_S_65 53 + #define ARLTBL_AGE_25 BIT_ULL(61) + #define ARLTBL_STATIC_25 BIT_ULL(62) + #define ARLTBL_VALID_25 BIT_ULL(63) +@@ -349,6 +347,9 @@ + #define ARLTBL_STATIC_89 BIT(14) + #define ARLTBL_VALID_89 BIT(15) + ++/* BCM5325/BCM565 ARL Table VID Entry N Registers (8 bit) */ ++#define B53_ARLTBL_VID_ENTRY_25(n) ((0x2 * (n)) + 0x30) ++ + /* Maximum number of bin entries in the ARL for all switches */ + #define B53_ARLTBL_MAX_BIN_ENTRIES 4 + +@@ -376,6 +377,8 @@ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 + #define ARL_SRCH_RSLT_PORT_ID_S_25 48 + #define ARL_SRCH_RSLT_PORT_ID_MASK_25 GENMASK_ULL(52, 48) ++#define ARL_SRCH_RSLT_VID_S_25 53 ++#define ARL_SRCH_RSLT_VID_MASK_25 GENMASK_ULL(60, 53) + + /* BCM5325/5365 Search result extend register (8 bit) */ + #define B53_ARL_SRCH_RSLT_EXT_25 0x2c +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch b/queue-6.18/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch new file mode 100644 index 0000000000..7da1d87871 --- /dev/null +++ b/queue-6.18/net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch @@ -0,0 +1,61 @@ +From 03a163d1207c2fa10037149df5b25d6d7d7d9242 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:22 +0100 +Subject: net: dsa: b53: fix CPU port unicast ARL entries for BCM5325/65 + +From: Jonas Gorski + +[ Upstream commit 85132103f700b1340fc17df8a981509d17bf4872 ] + +On BCM5325 and BCM5365, unicast ARL entries use 8 as the value for the +CPU port, so we need to translate it to/from 5 as used for the CPU port +at most other places. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251128080625.27181-5-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_priv.h | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 127ce7f6b16ba..80e7dd6169b47 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -344,12 +344,14 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + u64 mac_vid) + { + memset(ent, 0, sizeof(*ent)); +- ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & +- ARLTBL_DATA_PORT_ID_MASK_25; + ent->is_valid = !!(mac_vid & ARLTBL_VALID_25); + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); ++ ent->port = (mac_vid >> ARLTBL_DATA_PORT_ID_S_25) & ++ ARLTBL_DATA_PORT_ID_MASK_25; ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT) ++ ent->port = B53_CPU_PORT_25; + ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + +@@ -383,8 +385,11 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + const struct b53_arl_entry *ent) + { + *mac_vid = ether_addr_to_u64(ent->mac); +- *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << +- ARLTBL_DATA_PORT_ID_S_25; ++ if (is_unicast_ether_addr(ent->mac) && ent->port == B53_CPU_PORT_25) ++ *mac_vid |= (u64)B53_CPU_PORT << ARLTBL_DATA_PORT_ID_S_25; ++ else ++ *mac_vid |= (u64)(ent->port & ARLTBL_DATA_PORT_ID_MASK_25) << ++ ARLTBL_DATA_PORT_ID_S_25; + *mac_vid |= (u64)(ent->vid & ARLTBL_VID_MASK_25) << + ARLTBL_VID_S_65; + if (ent->is_valid) +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch b/queue-6.18/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch new file mode 100644 index 0000000000..75a3c33cec --- /dev/null +++ b/queue-6.18/net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch @@ -0,0 +1,45 @@ +From e695342d91f56f9388a788155d3d1790f3e855fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:20 +0100 +Subject: net: dsa: b53: fix extracting VID from entry for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 9316012dd01952f75e37035360138ccc786ef727 ] + +BCM5325/65's Entry register uses the highest three bits for +VALID/STATIC/AGE, so shifting by 53 only will add these to +b53_arl_entry::vid. + +So make sure to mask the vid value as well, to not get invalid VIDs. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-3-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_priv.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 458775f951643..2f44b3b6a0d9f 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -338,7 +338,7 @@ static inline void b53_arl_to_entry_25(struct b53_arl_entry *ent, + ent->is_age = !!(mac_vid & ARLTBL_AGE_25); + ent->is_static = !!(mac_vid & ARLTBL_STATIC_25); + u64_to_ether_addr(mac_vid, ent->mac); +- ent->vid = mac_vid >> ARLTBL_VID_S_65; ++ ent->vid = (mac_vid >> ARLTBL_VID_S_65) & ARLTBL_VID_MASK_25; + } + + static inline void b53_arl_from_entry(u64 *mac_vid, u32 *fwd_entry, +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch b/queue-6.18/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch new file mode 100644 index 0000000000..f2d217b269 --- /dev/null +++ b/queue-6.18/net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch @@ -0,0 +1,48 @@ +From 7001e8849a0400cc2da8705aabf91122f6fa68a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:19 +0100 +Subject: net: dsa: b53: fix VLAN_ID_IDX write size for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 6f268e275c74dae0536e0b61982a8db25bcf4f16 ] + +Since BCM5325 and BCM5365 only support up to 256 VLANs, the VLAN_ID_IDX +register is only 8 bit wide, not 16 bit, so use an appropriate accessor. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-2-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index eb767edc4c135..a09ed32dccc07 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1924,8 +1924,12 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + + /* Perform a read for the given MAC and VID */ + b53_write48(dev, B53_ARLIO_PAGE, B53_MAC_ADDR_IDX, mac); +- if (!is5325m(dev)) +- b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ if (!is5325m(dev)) { ++ if (is5325(dev) || is5365(dev)) ++ b53_write8(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ else ++ b53_write16(dev, B53_ARLIO_PAGE, B53_VLAN_ID_IDX, vid); ++ } + + /* Issue a read operation for this MAC */ + ret = b53_arl_rw_op(dev, 1); +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch b/queue-6.18/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch new file mode 100644 index 0000000000..eeeee19f35 --- /dev/null +++ b/queue-6.18/net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch @@ -0,0 +1,361 @@ +From 0069031669ad3a31838eb816f246f289888c945b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:47 +0100 +Subject: net: dsa: b53: move ARL entry functions into ops struct + +From: Jonas Gorski + +[ Upstream commit a7e73339ad46ade76d29fb6cc7d7854222608c26 ] + +Now that the differences in ARL entry formats are neatly contained into +functions per chip family, wrap them into an ops struct and add wrapper +functions to access them. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-7-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 67 ++++++++++++++++++++++---------- + drivers/net/dsa/b53/b53_priv.h | 30 ++++++++++++++ + 2 files changed, 76 insertions(+), 21 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 190eb11644917..50ed9b7157197 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1890,10 +1890,7 @@ static int b53_arl_read(struct b53_device *dev, const u8 *mac, + + /* Read the bins */ + for (i = 0; i < dev->num_arl_bins; i++) { +- if (is5325(dev) || is5365(dev)) +- b53_arl_read_entry_25(dev, ent, i); +- else +- b53_arl_read_entry_95(dev, ent, i); ++ b53_arl_read_entry(dev, ent, i); + + if (!ent->is_valid) { + set_bit(i, free_bins); +@@ -1979,10 +1976,7 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + ent.is_static = true; + ent.is_age = false; + memcpy(ent.mac, addr, ETH_ALEN); +- if (is5325(dev) || is5365(dev)) +- b53_arl_write_entry_25(dev, &ent, idx); +- else +- b53_arl_write_entry_95(dev, &ent, idx); ++ b53_arl_write_entry(dev, &ent, idx); + + return b53_arl_rw_op(dev, 0); + } +@@ -2093,17 +2087,6 @@ static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, + b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + +-static void b53_arl_search_rd(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) +-{ +- if (is5325(dev)) +- b53_arl_search_read_25(dev, idx, ent); +- else if (is5365(dev)) +- b53_arl_search_read_65(dev, idx, ent); +- else +- b53_arl_search_read_95(dev, idx, ent); +-} +- + static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, + dsa_fdb_dump_cb_t *cb, void *data) + { +@@ -2137,13 +2120,13 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, + if (ret) + break; + +- b53_arl_search_rd(priv, 0, &results[0]); ++ b53_arl_search_read(priv, 0, &results[0]); + ret = b53_fdb_copy(port, &results[0], cb, data); + if (ret) + break; + + if (results_per_hit == 2) { +- b53_arl_search_rd(priv, 1, &results[1]); ++ b53_arl_search_read(priv, 1, &results[1]); + ret = b53_fdb_copy(port, &results[1], cb, data); + if (ret) + break; +@@ -2669,6 +2652,24 @@ static const struct dsa_switch_ops b53_switch_ops = { + .port_change_mtu = b53_change_mtu, + }; + ++static const struct b53_arl_ops b53_arl_ops_25 = { ++ .arl_read_entry = b53_arl_read_entry_25, ++ .arl_write_entry = b53_arl_write_entry_25, ++ .arl_search_read = b53_arl_search_read_25, ++}; ++ ++static const struct b53_arl_ops b53_arl_ops_65 = { ++ .arl_read_entry = b53_arl_read_entry_25, ++ .arl_write_entry = b53_arl_write_entry_25, ++ .arl_search_read = b53_arl_search_read_65, ++}; ++ ++static const struct b53_arl_ops b53_arl_ops_95 = { ++ .arl_read_entry = b53_arl_read_entry_95, ++ .arl_write_entry = b53_arl_write_entry_95, ++ .arl_search_read = b53_arl_search_read_95, ++}; ++ + struct b53_chip_data { + u32 chip_id; + const char *dev_name; +@@ -2682,6 +2683,7 @@ struct b53_chip_data { + u8 duplex_reg; + u8 jumbo_pm_reg; + u8 jumbo_size_reg; ++ const struct b53_arl_ops *arl_ops; + }; + + #define B53_VTA_REGS \ +@@ -2701,6 +2703,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, ++ .arl_ops = &b53_arl_ops_25, + }, + { + .chip_id = BCM5365_DEVICE_ID, +@@ -2711,6 +2714,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, ++ .arl_ops = &b53_arl_ops_65, + }, + { + .chip_id = BCM5389_DEVICE_ID, +@@ -2724,6 +2728,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5395_DEVICE_ID, +@@ -2737,6 +2742,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5397_DEVICE_ID, +@@ -2750,6 +2756,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM5398_DEVICE_ID, +@@ -2763,6 +2770,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53101_DEVICE_ID, +@@ -2776,6 +2784,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53115_DEVICE_ID, +@@ -2789,6 +2798,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53125_DEVICE_ID, +@@ -2802,6 +2812,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53128_DEVICE_ID, +@@ -2815,6 +2826,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM63XX_DEVICE_ID, +@@ -2828,6 +2840,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_63XX, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53010_DEVICE_ID, +@@ -2841,6 +2854,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53011_DEVICE_ID, +@@ -2854,6 +2868,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53012_DEVICE_ID, +@@ -2867,6 +2882,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53018_DEVICE_ID, +@@ -2880,6 +2896,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53019_DEVICE_ID, +@@ -2893,6 +2910,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM58XX_DEVICE_ID, +@@ -2906,6 +2924,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM583XX_DEVICE_ID, +@@ -2919,6 +2938,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + /* Starfighter 2 */ + { +@@ -2933,6 +2953,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM7445_DEVICE_ID, +@@ -2946,6 +2967,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM7278_DEVICE_ID, +@@ -2959,6 +2981,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + { + .chip_id = BCM53134_DEVICE_ID, +@@ -2973,6 +2996,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .duplex_reg = B53_DUPLEX_STAT_GE, + .jumbo_pm_reg = B53_JUMBO_PORT_MASK, + .jumbo_size_reg = B53_JUMBO_MAX_SIZE, ++ .arl_ops = &b53_arl_ops_95, + }, + }; + +@@ -3001,6 +3025,7 @@ static int b53_switch_init(struct b53_device *dev) + dev->num_vlans = chip->vlans; + dev->num_arl_bins = chip->arl_bins; + dev->num_arl_buckets = chip->arl_buckets; ++ dev->arl_ops = chip->arl_ops; + break; + } + } +diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h +index 2f44b3b6a0d9f..c6e2d5e41c758 100644 +--- a/drivers/net/dsa/b53/b53_priv.h ++++ b/drivers/net/dsa/b53/b53_priv.h +@@ -58,6 +58,17 @@ struct b53_io_ops { + bool link_up); + }; + ++struct b53_arl_entry; ++ ++struct b53_arl_ops { ++ void (*arl_read_entry)(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx); ++ void (*arl_write_entry)(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx); ++ void (*arl_search_read)(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent); ++}; ++ + #define B53_INVALID_LANE 0xff + + enum { +@@ -127,6 +138,7 @@ struct b53_device { + struct mutex stats_mutex; + struct mutex arl_mutex; + const struct b53_io_ops *ops; ++ const struct b53_arl_ops *arl_ops; + + /* chip specific data */ + u32 chip_id; +@@ -371,6 +383,24 @@ static inline void b53_arl_from_entry_25(u64 *mac_vid, + *mac_vid |= ARLTBL_AGE_25; + } + ++static inline void b53_arl_read_entry(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ dev->arl_ops->arl_read_entry(dev, ent, idx); ++} ++ ++static inline void b53_arl_write_entry(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ dev->arl_ops->arl_write_entry(dev, ent, idx); ++} ++ ++static inline void b53_arl_search_read(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ dev->arl_ops->arl_search_read(dev, idx, ent); ++} ++ + #ifdef CONFIG_BCM47XX + + #include +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch b/queue-6.18/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch new file mode 100644 index 0000000000..cc12a70734 --- /dev/null +++ b/queue-6.18/net-dsa-b53-move-reading-arl-entries-into-their-own-.patch @@ -0,0 +1,127 @@ +From 282d9556e3a188889c0215d5b6642749b76c218d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:43 +0100 +Subject: net: dsa: b53: move reading ARL entries into their own function + +From: Jonas Gorski + +[ Upstream commit 4a291fe7226736a465ddb3fa93c21fcef7162ec7 ] + +Instead of duplicating the whole code iterating over all bins for +BCM5325, factor out reading and parsing the entry into its own +functions, and name it the modern one after the first chip with that ARL +format, (BCM53)95. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-3-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 69 +++++++++++--------------------- + 1 file changed, 23 insertions(+), 46 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 4d8de90fb4ab8..41dcd2d03230d 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1830,48 +1830,30 @@ static int b53_arl_rw_op(struct b53_device *dev, unsigned int op) + return b53_arl_op_wait(dev); + } + +-static int b53_arl_read(struct b53_device *dev, const u8 *mac, +- u16 vid, struct b53_arl_entry *ent, u8 *idx) ++static void b53_arl_read_entry_25(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) + { +- DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); +- unsigned int i; +- int ret; +- +- ret = b53_arl_op_wait(dev); +- if (ret) +- return ret; +- +- bitmap_zero(free_bins, dev->num_arl_bins); +- +- /* Read the bins */ +- for (i = 0; i < dev->num_arl_bins; i++) { +- u64 mac_vid; +- u32 fwd_entry; ++ u64 mac_vid; + +- b53_read64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid); +- b53_read32(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_DATA_ENTRY(i), &fwd_entry); +- b53_arl_to_entry(ent, mac_vid, fwd_entry); ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} + +- if (!ent->is_valid) { +- set_bit(i, free_bins); +- continue; +- } +- if (!ether_addr_equal(ent->mac, mac)) +- continue; +- if (dev->vlan_enabled && ent->vid != vid) +- continue; +- *idx = i; +- return 0; +- } ++static void b53_arl_read_entry_95(struct b53_device *dev, ++ struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; + +- *idx = find_first_bit(free_bins, dev->num_arl_bins); +- return *idx >= dev->num_arl_bins ? -ENOSPC : -ENOENT; ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ &mac_vid); ++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), &fwd_entry); ++ b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + +-static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, +- u16 vid, struct b53_arl_entry *ent, u8 *idx) ++static int b53_arl_read(struct b53_device *dev, const u8 *mac, ++ u16 vid, struct b53_arl_entry *ent, u8 *idx) + { + DECLARE_BITMAP(free_bins, B53_ARLTBL_MAX_BIN_ENTRIES); + unsigned int i; +@@ -1885,12 +1867,10 @@ static int b53_arl_read_25(struct b53_device *dev, const u8 *mac, + + /* Read the bins */ + for (i = 0; i < dev->num_arl_bins; i++) { +- u64 mac_vid; +- +- b53_read64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(i), &mac_vid); +- +- b53_arl_to_entry_25(ent, mac_vid); ++ if (is5325(dev) || is5365(dev)) ++ b53_arl_read_entry_25(dev, ent, i); ++ else ++ b53_arl_read_entry_95(dev, ent, i); + + if (!ent->is_valid) { + set_bit(i, free_bins); +@@ -1934,10 +1914,7 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + if (ret) + return ret; + +- if (is5325(dev) || is5365(dev)) +- ret = b53_arl_read_25(dev, addr, vid, &ent, &idx); +- else +- ret = b53_arl_read(dev, addr, vid, &ent, &idx); ++ ret = b53_arl_read(dev, addr, vid, &ent, &idx); + + /* If this is a read, just finish now */ + if (op) +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch b/queue-6.18/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch new file mode 100644 index 0000000000..91cbc55270 --- /dev/null +++ b/queue-6.18/net-dsa-b53-move-writing-arl-entries-into-their-own-.patch @@ -0,0 +1,103 @@ +From 10249ce9ce79d86d345b5f37397fbb1f3961999c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:44 +0100 +Subject: net: dsa: b53: move writing ARL entries into their own functions + +From: Jonas Gorski + +[ Upstream commit bf6e9d2ae1dbafee53ec4ccd126595172e1e5278 ] + +Move writing ARL entries into individual functions for each format. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-4-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 38 ++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 12 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 41dcd2d03230d..4c418e0531f73 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -1840,6 +1840,16 @@ static void b53_arl_read_entry_25(struct b53_device *dev, + b53_arl_to_entry_25(ent, mac_vid); + } + ++static void b53_arl_write_entry_25(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u64 mac_vid; ++ ++ b53_arl_from_entry_25(&mac_vid, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ mac_vid); ++} ++ + static void b53_arl_read_entry_95(struct b53_device *dev, + struct b53_arl_entry *ent, u8 idx) + { +@@ -1852,6 +1862,19 @@ static void b53_arl_read_entry_95(struct b53_device *dev, + b53_arl_to_entry(ent, mac_vid, fwd_entry); + } + ++static void b53_arl_write_entry_95(struct b53_device *dev, ++ const struct b53_arl_entry *ent, u8 idx) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_arl_from_entry(&mac_vid, &fwd_entry, ent); ++ b53_write64(dev, B53_ARLIO_PAGE, B53_ARLTBL_MAC_VID_ENTRY(idx), ++ mac_vid); ++ b53_write32(dev, B53_ARLIO_PAGE, B53_ARLTBL_DATA_ENTRY(idx), ++ fwd_entry); ++} ++ + static int b53_arl_read(struct b53_device *dev, const u8 *mac, + u16 vid, struct b53_arl_entry *ent, u8 *idx) + { +@@ -1892,9 +1915,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + const unsigned char *addr, u16 vid, bool is_valid) + { + struct b53_arl_entry ent; +- u32 fwd_entry; +- u64 mac, mac_vid = 0; + u8 idx = 0; ++ u64 mac; + int ret; + + /* Convert the array into a 64-bit MAC */ +@@ -1931,7 +1953,6 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + /* We could not find a matching MAC, so reset to a new entry */ + dev_dbg(dev->dev, "{%pM,%.4d} not found, using idx: %d\n", + addr, vid, idx); +- fwd_entry = 0; + break; + default: + dev_dbg(dev->dev, "{%pM,%.4d} found, using idx: %d\n", +@@ -1959,16 +1980,9 @@ static int b53_arl_op(struct b53_device *dev, int op, int port, + ent.is_age = false; + memcpy(ent.mac, addr, ETH_ALEN); + if (is5325(dev) || is5365(dev)) +- b53_arl_from_entry_25(&mac_vid, &ent); ++ b53_arl_write_entry_25(dev, &ent, idx); + else +- b53_arl_from_entry(&mac_vid, &fwd_entry, &ent); +- +- b53_write64(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_MAC_VID_ENTRY(idx), mac_vid); +- +- if (!is5325(dev) && !is5365(dev)) +- b53_write32(dev, B53_ARLIO_PAGE, +- B53_ARLTBL_DATA_ENTRY(idx), fwd_entry); ++ b53_arl_write_entry_95(dev, &ent, idx); + + return b53_arl_rw_op(dev, 0); + } +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch b/queue-6.18/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch new file mode 100644 index 0000000000..d478cfe0b8 --- /dev/null +++ b/queue-6.18/net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch @@ -0,0 +1,96 @@ +From 23c45b445f677cc0310e8e8eda7d2d05f9f125fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:45 +0100 +Subject: net: dsa: b53: provide accessors for accessing ARL_SRCH_CTL + +From: Jonas Gorski + +[ Upstream commit 1716be6db04af53bac9b869f01156a460595cf41 ] + +In order to more easily support more formats, move accessing +ARL_SRCH_CTL into helper functions to contain the differences. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-5-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 37 +++++++++++++++++++++----------- + 1 file changed, 24 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 4c418e0531f73..38e6fa05042ca 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2017,18 +2017,37 @@ int b53_fdb_del(struct dsa_switch *ds, int port, + } + EXPORT_SYMBOL(b53_fdb_del); + +-static int b53_arl_search_wait(struct b53_device *dev) ++static void b53_read_arl_srch_ctl(struct b53_device *dev, u8 *val) + { +- unsigned int timeout = 1000; +- u8 reg, offset; ++ u8 offset; ++ ++ if (is5325(dev) || is5365(dev)) ++ offset = B53_ARL_SRCH_CTL_25; ++ else ++ offset = B53_ARL_SRCH_CTL; ++ ++ b53_read8(dev, B53_ARLIO_PAGE, offset, val); ++} ++ ++static void b53_write_arl_srch_ctl(struct b53_device *dev, u8 val) ++{ ++ u8 offset; + + if (is5325(dev) || is5365(dev)) + offset = B53_ARL_SRCH_CTL_25; + else + offset = B53_ARL_SRCH_CTL; + ++ b53_write8(dev, B53_ARLIO_PAGE, offset, val); ++} ++ ++static int b53_arl_search_wait(struct b53_device *dev) ++{ ++ unsigned int timeout = 1000; ++ u8 reg; ++ + do { +- b53_read8(dev, B53_ARLIO_PAGE, offset, ®); ++ b53_read_arl_srch_ctl(dev, ®); + if (!(reg & ARL_SRCH_STDN)) + return -ENOENT; + +@@ -2083,23 +2102,15 @@ int b53_fdb_dump(struct dsa_switch *ds, int port, + unsigned int count = 0, results_per_hit = 1; + struct b53_device *priv = ds->priv; + struct b53_arl_entry results[2]; +- u8 offset; + int ret; +- u8 reg; + + if (priv->num_arl_bins > 2) + results_per_hit = 2; + + mutex_lock(&priv->arl_mutex); + +- if (is5325(priv) || is5365(priv)) +- offset = B53_ARL_SRCH_CTL_25; +- else +- offset = B53_ARL_SRCH_CTL; +- + /* Start search operation */ +- reg = ARL_SRCH_STDN; +- b53_write8(priv, B53_ARLIO_PAGE, offset, reg); ++ b53_write_arl_srch_ctl(priv, ARL_SRCH_STDN); + + do { + ret = b53_arl_search_wait(priv); +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-split-reading-search-entry-into-their-ow.patch b/queue-6.18/net-dsa-b53-split-reading-search-entry-into-their-ow.patch new file mode 100644 index 0000000000..07ab83f3dc --- /dev/null +++ b/queue-6.18/net-dsa-b53-split-reading-search-entry-into-their-ow.patch @@ -0,0 +1,95 @@ +From 69864a428e7e172a894cbe165b0d996c71b6a482 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 09:07:46 +0100 +Subject: net: dsa: b53: split reading search entry into their own functions + +From: Jonas Gorski + +[ Upstream commit e0c476f325a8c9b961a3d446c24d3c8ecae7d186 ] + +Split reading search entries into a function for each format. + +Signed-off-by: Jonas Gorski +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251107080749.26936-6-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 8e46aacea426 ("net: dsa: b53: use same ARL search result offset for BCM5325/65") +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 56 ++++++++++++++++++++++---------- + 1 file changed, 38 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index 38e6fa05042ca..190eb11644917 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2060,28 +2060,48 @@ static int b53_arl_search_wait(struct b53_device *dev) + return -ETIMEDOUT; + } + +-static void b53_arl_search_rd(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) ++static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) + { + u64 mac_vid; + +- if (is5325(dev)) { +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +- } else if (is5365(dev)) { +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +- } else { +- u32 fwd_entry; ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_25, ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} + +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx), +- &mac_vid); +- b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx), +- &fwd_entry); +- b53_arl_to_entry(ent, mac_vid, fwd_entry); +- } ++static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, ++ &mac_vid); ++ b53_arl_to_entry_25(ent, mac_vid); ++} ++ ++static void b53_arl_search_read_95(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ u32 fwd_entry; ++ u64 mac_vid; ++ ++ b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_MACVID(idx), ++ &mac_vid); ++ b53_read32(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL(idx), ++ &fwd_entry); ++ b53_arl_to_entry(ent, mac_vid, fwd_entry); ++} ++ ++static void b53_arl_search_rd(struct b53_device *dev, u8 idx, ++ struct b53_arl_entry *ent) ++{ ++ if (is5325(dev)) ++ b53_arl_search_read_25(dev, idx, ent); ++ else if (is5365(dev)) ++ b53_arl_search_read_65(dev, idx, ent); ++ else ++ b53_arl_search_read_95(dev, idx, ent); + } + + static int b53_fdb_copy(int port, const struct b53_arl_entry *ent, +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch b/queue-6.18/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch new file mode 100644 index 0000000000..e6742bc178 --- /dev/null +++ b/queue-6.18/net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch @@ -0,0 +1,90 @@ +From 1ab6f0b681930278b3b02d7726d292cecf24c557 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 09:06:21 +0100 +Subject: net: dsa: b53: use same ARL search result offset for BCM5325/65 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jonas Gorski + +[ Upstream commit 8e46aacea4264bcb8d4265fb07577afff58ae78d ] + +BCM5365's search result is at the same offset as BCM5325's search +result, and they (mostly) share the same format, so switch BCM5365 to +BCM5325's arl ops. + +Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365") +Reviewed-by: Florian Fainelli +Tested-by: Álvaro Fernández Rojas +Signed-off-by: Jonas Gorski +Link: https://patch.msgid.link/20251128080625.27181-4-jonas.gorski@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/b53/b53_common.c | 18 +----------------- + drivers/net/dsa/b53/b53_regs.h | 4 +--- + 2 files changed, 2 insertions(+), 20 deletions(-) + +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index dedbd53412871..68e9162087ab4 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -2093,16 +2093,6 @@ static void b53_arl_search_read_25(struct b53_device *dev, u8 idx, + b53_arl_to_entry_25(ent, mac_vid); + } + +-static void b53_arl_search_read_65(struct b53_device *dev, u8 idx, +- struct b53_arl_entry *ent) +-{ +- u64 mac_vid; +- +- b53_read64(dev, B53_ARLIO_PAGE, B53_ARL_SRCH_RSTL_0_MACVID_65, +- &mac_vid); +- b53_arl_to_entry_25(ent, mac_vid); +-} +- + static void b53_arl_search_read_89(struct b53_device *dev, u8 idx, + struct b53_arl_entry *ent) + { +@@ -2699,12 +2689,6 @@ static const struct b53_arl_ops b53_arl_ops_25 = { + .arl_search_read = b53_arl_search_read_25, + }; + +-static const struct b53_arl_ops b53_arl_ops_65 = { +- .arl_read_entry = b53_arl_read_entry_25, +- .arl_write_entry = b53_arl_write_entry_25, +- .arl_search_read = b53_arl_search_read_65, +-}; +- + static const struct b53_arl_ops b53_arl_ops_89 = { + .arl_read_entry = b53_arl_read_entry_89, + .arl_write_entry = b53_arl_write_entry_89, +@@ -2761,7 +2745,7 @@ static const struct b53_chip_data b53_switch_chips[] = { + .arl_buckets = 1024, + .imp_port = 5, + .duplex_reg = B53_DUPLEX_STAT_FE, +- .arl_ops = &b53_arl_ops_65, ++ .arl_ops = &b53_arl_ops_25, + }, + { + .chip_id = BCM5389_DEVICE_ID, +diff --git a/drivers/net/dsa/b53/b53_regs.h b/drivers/net/dsa/b53/b53_regs.h +index d9026cf865549..f2a3696d122fa 100644 +--- a/drivers/net/dsa/b53/b53_regs.h ++++ b/drivers/net/dsa/b53/b53_regs.h +@@ -370,10 +370,8 @@ + #define B53_ARL_SRCH_RSTL_0_MACVID 0x60 + #define B53_ARL_SRCH_RSLT_MACVID_89 0x33 + +-/* Single register search result on 5325 */ ++/* Single register search result on 5325/5365 */ + #define B53_ARL_SRCH_RSTL_0_MACVID_25 0x24 +-/* Single register search result on 5365 */ +-#define B53_ARL_SRCH_RSTL_0_MACVID_65 0x30 + + /* ARL Search Data Result (32 bit) */ + #define B53_ARL_SRCH_RSTL_0 0x68 +-- +2.51.0 + diff --git a/queue-6.18/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch b/queue-6.18/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch new file mode 100644 index 0000000000..27674b68d1 --- /dev/null +++ b/queue-6.18/net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch @@ -0,0 +1,83 @@ +From 9d0ddddad5a008622702786187d78ae17398bec9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:46 +0200 +Subject: net: dsa: xrs700x: reject unsupported HSR configurations + +From: Vladimir Oltean + +[ Upstream commit 30296ac7642652428396222e720718f2661e9425 ] + +As discussed here: +https://lore.kernel.org/netdev/20240620090210.drop6jwh7e5qw556@skbuf/ + +the fact is that the xrs700x.c driver only supports offloading +HSR_PT_SLAVE_A and HSR_PT_SLAVE_B (which were the only port types at the +time the offload was written, _for this driver_). + +Up until now, the API did not explicitly tell offloading drivers what +port has what role. So xrs700x can get confused and think that it can +support a configuration which it actually can't. There was a table in +the attached link which gave an example: + +$ ip link add name hsr0 type hsr slave1 swp0 slave2 swp1 \ + interlink swp2 supervision 45 version 1 + + HSR_PT_SLAVE_A HSR_PT_SLAVE_B HSR_PT_INTERLINK + ---------------------------------------------------------------- + user + space 0 1 2 + requests + ---------------------------------------------------------------- + XRS700X + driver 1 2 - + understands + +The switch would act as if the ring ports were swp1 and swp2. + +Now that we have explicit hsr_get_port_type() API, let's use that to +work around the unintended semantical changes of the offloading API +brought by the introduction of interlink ports in HSR. + +Fixes: 5055cccfc2d1 ("net: hsr: Provide RedBox support (HSR-SAN)") +Cc: Lukasz Majewski +Signed-off-by: Vladimir Oltean +Reviewed-by: George McCollister +Link: https://patch.msgid.link/20251130131657.65080-5-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/dsa/xrs700x/xrs700x.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c +index 4dbcc49a9e526..0a05f4156ef4d 100644 +--- a/drivers/net/dsa/xrs700x/xrs700x.c ++++ b/drivers/net/dsa/xrs700x/xrs700x.c +@@ -566,6 +566,7 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + struct xrs700x *priv = ds->priv; + struct net_device *user; + int ret, i, hsr_pair[2]; ++ enum hsr_port_type type; + enum hsr_version ver; + bool fwd = false; + +@@ -589,6 +590,16 @@ static int xrs700x_hsr_join(struct dsa_switch *ds, int port, + return -EOPNOTSUPP; + } + ++ ret = hsr_get_port_type(hsr, dsa_to_port(ds, port)->user, &type); ++ if (ret) ++ return ret; ++ ++ if (type != HSR_PT_SLAVE_A && type != HSR_PT_SLAVE_B) { ++ NL_SET_ERR_MSG_MOD(extack, ++ "Only HSR slave ports can be offloaded"); ++ return -EOPNOTSUPP; ++ } ++ + dsa_hsr_foreach_port(dp, ds, hsr) { + if (dp->index != port) { + partner = dp; +-- +2.51.0 + diff --git a/queue-6.18/net-export-netdev_get_by_index_lock.patch b/queue-6.18/net-export-netdev_get_by_index_lock.patch new file mode 100644 index 0000000000..d9315a2032 --- /dev/null +++ b/queue-6.18/net-export-netdev_get_by_index_lock.patch @@ -0,0 +1,49 @@ +From 44a0661e153e5b4c5947a1a05cacaa4495a1372b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 19:24:48 -0700 +Subject: net: export netdev_get_by_index_lock() + +From: David Wei + +[ Upstream commit c07a491c1b735e0c27454ea5c27a446d43401b1e ] + +Need to call netdev_get_by_index_lock() from io_uring/zcrx.c, but it is +currently private to net. Export the function in linux/netdevice.h. + +Signed-off-by: David Wei +Acked-by: Jakub Kicinski +Signed-off-by: Jens Axboe +Stable-dep-of: b6c5f9454ef3 ("io_uring/zcrx: call netdev_queue_get_dma_dev() under instance lock") +Signed-off-by: Sasha Levin +--- + include/linux/netdevice.h | 1 + + net/core/dev.h | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index d1a687444b275..77c46a2823eca 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -3401,6 +3401,7 @@ struct net_device *dev_get_by_index(struct net *net, int ifindex); + struct net_device *__dev_get_by_index(struct net *net, int ifindex); + struct net_device *netdev_get_by_index(struct net *net, int ifindex, + netdevice_tracker *tracker, gfp_t gfp); ++struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex); + struct net_device *netdev_get_by_name(struct net *net, const char *name, + netdevice_tracker *tracker, gfp_t gfp); + struct net_device *netdev_get_by_flags_rcu(struct net *net, netdevice_tracker *tracker, +diff --git a/net/core/dev.h b/net/core/dev.h +index 900880e8b5b4b..df8a90fe89f8f 100644 +--- a/net/core/dev.h ++++ b/net/core/dev.h +@@ -29,7 +29,6 @@ struct napi_struct * + netdev_napi_by_id_lock(struct net *net, unsigned int napi_id); + struct net_device *dev_get_by_napi_id(unsigned int napi_id); + +-struct net_device *netdev_get_by_index_lock(struct net *net, int ifindex); + struct net_device *__netdev_put_lock(struct net_device *dev, struct net *net); + struct net_device * + netdev_xa_find_lock(struct net *net, struct net_device *dev, +-- +2.51.0 + diff --git a/queue-6.18/net-hsr-create-an-api-to-get-hsr-port-type.patch b/queue-6.18/net-hsr-create-an-api-to-get-hsr-port-type.patch new file mode 100644 index 0000000000..d4b90019c1 --- /dev/null +++ b/queue-6.18/net-hsr-create-an-api-to-get-hsr-port-type.patch @@ -0,0 +1,135 @@ +From a1ed0d40a8c53f2e19430db68acbcc1d3cd5fcbb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 30 Nov 2025 15:16:44 +0200 +Subject: net: hsr: create an API to get hsr port type +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiaoliang Yang + +[ Upstream commit a0244e76213980f3b9bb5d40b0b6705fcf24230d ] + +Since the introduction of HSR_PT_INTERLINK in commit 5055cccfc2d1 ("net: +hsr: Provide RedBox support (HSR-SAN)"), we see that different port +types require different settings for hardware offload, which was not the +case before when we only had HSR_PT_SLAVE_A and HSR_PT_SLAVE_B. But +there is currently no way to know which port is which type, so create +the hsr_get_port_type() API function and export it. + +When hsr_get_port_type() is called from the device driver, the port can +must be found in the HSR port list. An important use case is for this +function to work from offloading drivers' NETDEV_CHANGEUPPER handler, +which is triggered by hsr_portdev_setup() -> netdev_master_upper_dev_link(). +Therefore, we need to move the addition of the hsr_port to the HSR port +list prior to calling hsr_portdev_setup(). This makes the error +restoration path also more similar to hsr_del_port(), where +kfree_rcu(port) is already used. + +Cc: Sebastian Andrzej Siewior +Cc: Lukasz Majewski +Signed-off-by: Xiaoliang Yang +Signed-off-by: Vladimir Oltean +Reviewed-by: Łukasz Majewski +Link: https://patch.msgid.link/20251130131657.65080-3-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 30296ac76426 ("net: dsa: xrs700x: reject unsupported HSR configurations") +Signed-off-by: Sasha Levin +--- + include/linux/if_hsr.h | 9 +++++++++ + net/hsr/hsr_device.c | 20 ++++++++++++++++++++ + net/hsr/hsr_slave.c | 7 ++++--- + 3 files changed, 33 insertions(+), 3 deletions(-) + +diff --git a/include/linux/if_hsr.h b/include/linux/if_hsr.h +index d7941fd880329..f4cf2dd36d193 100644 +--- a/include/linux/if_hsr.h ++++ b/include/linux/if_hsr.h +@@ -43,6 +43,8 @@ extern bool is_hsr_master(struct net_device *dev); + extern int hsr_get_version(struct net_device *dev, enum hsr_version *ver); + struct net_device *hsr_get_port_ndev(struct net_device *ndev, + enum hsr_port_type pt); ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type); + #else + static inline bool is_hsr_master(struct net_device *dev) + { +@@ -59,6 +61,13 @@ static inline struct net_device *hsr_get_port_ndev(struct net_device *ndev, + { + return ERR_PTR(-EINVAL); + } ++ ++static inline int hsr_get_port_type(struct net_device *hsr_dev, ++ struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ return -EINVAL; ++} + #endif /* CONFIG_HSR */ + + #endif /*_LINUX_IF_HSR_H_*/ +diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c +index 492cbc78ab75a..d1bfc49b5f017 100644 +--- a/net/hsr/hsr_device.c ++++ b/net/hsr/hsr_device.c +@@ -690,6 +690,26 @@ struct net_device *hsr_get_port_ndev(struct net_device *ndev, + } + EXPORT_SYMBOL(hsr_get_port_ndev); + ++int hsr_get_port_type(struct net_device *hsr_dev, struct net_device *dev, ++ enum hsr_port_type *type) ++{ ++ struct hsr_priv *hsr = netdev_priv(hsr_dev); ++ struct hsr_port *port; ++ ++ rcu_read_lock(); ++ hsr_for_each_port(hsr, port) { ++ if (port->dev == dev) { ++ *type = port->type; ++ rcu_read_unlock(); ++ return 0; ++ } ++ } ++ rcu_read_unlock(); ++ ++ return -EINVAL; ++} ++EXPORT_SYMBOL(hsr_get_port_type); ++ + /* Default multicast address for HSR Supervision frames */ + static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = { + 0x01, 0x15, 0x4e, 0x00, 0x01, 0x00 +diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c +index 8177ac6c2d26d..afe06ba00ea44 100644 +--- a/net/hsr/hsr_slave.c ++++ b/net/hsr/hsr_slave.c +@@ -207,14 +207,14 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + port->type = type; + ether_addr_copy(port->original_macaddress, dev->dev_addr); + ++ list_add_tail_rcu(&port->port_list, &hsr->ports); ++ + if (type != HSR_PT_MASTER) { + res = hsr_portdev_setup(hsr, dev, port, extack); + if (res) + goto fail_dev_setup; + } + +- list_add_tail_rcu(&port->port_list, &hsr->ports); +- + master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); + netdev_update_features(master->dev); + dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); +@@ -222,7 +222,8 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev, + return 0; + + fail_dev_setup: +- kfree(port); ++ list_del_rcu(&port->port_list); ++ kfree_rcu(port, rcu); + return res; + } + +-- +2.51.0 + diff --git a/queue-6.18/net-netpoll-initialize-work-queue-before-error-check.patch b/queue-6.18/net-netpoll-initialize-work-queue-before-error-check.patch new file mode 100644 index 0000000000..039ebd5589 --- /dev/null +++ b/queue-6.18/net-netpoll-initialize-work-queue-before-error-check.patch @@ -0,0 +1,56 @@ +From b0a9de8e4cb2b8a9f5490ae4f1f1b1ddef3d4c31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 07:30:15 -0800 +Subject: net: netpoll: initialize work queue before error checks + +From: Breno Leitao + +[ Upstream commit e5235eb6cfe02a51256013a78f7b28779a7740d5 ] + +Prevent a kernel warning when netconsole setup fails on devices with +IFF_DISABLE_NETPOLL flag. The warning (at kernel/workqueue.c:4242 in +__flush_work) occurs because the cleanup path tries to cancel an +uninitialized work queue. + +When __netpoll_setup() encounters a device with IFF_DISABLE_NETPOLL, +it fails early and calls skb_pool_flush() for cleanup. This function +calls cancel_work_sync(&np->refill_wq), but refill_wq hasn't been +initialized yet, triggering the warning. + +Move INIT_WORK() to the beginning of __netpoll_setup(), ensuring the +work queue is properly initialized before any potential failure points. +This allows the cleanup path to safely cancel the work queue regardless +of where the setup fails. + +Fixes: 248f6571fd4c5 ("netpoll: Optimize skb refilling on critical path") +Signed-off-by: Breno Leitao +Link: https://patch.msgid.link/20251127-netpoll_fix_init_work-v1-1-65c07806d736@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 331764845e8fa..09f72f10813cc 100644 +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -554,6 +554,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) + int err; + + skb_queue_head_init(&np->skb_pool); ++ INIT_WORK(&np->refill_wq, refill_skbs_work_handler); + + if (ndev->priv_flags & IFF_DISABLE_NETPOLL) { + np_err(np, "%s doesn't support polling, aborting\n", +@@ -591,7 +592,6 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) + + /* fill up the skb queue */ + refill_skbs(np); +- INIT_WORK(&np->refill_wq, refill_skbs_work_handler); + + /* last thing to do is link it to the net device structure */ + rcu_assign_pointer(ndev->npinfo, npinfo); +-- +2.51.0 + diff --git a/queue-6.18/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch b/queue-6.18/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch new file mode 100644 index 0000000000..47e8c9ad8b --- /dev/null +++ b/queue-6.18/net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch @@ -0,0 +1,102 @@ +From f8325138cee96b1e58c28cc4a9a32f93d9eed5e9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 08:38:04 +0800 +Subject: net: phy: Add helper for fixing RGMII PHY mode based on internal mac + delay + +From: Inochi Amaoto + +[ Upstream commit 24afd7827efb7c69adfc41835390470e3eec4740 ] + +The "phy-mode" property of devicetree indicates whether the PCB has +delay now, which means the mac needs to modify the PHY mode based +on whether there is an internal delay in the mac. + +This modification is similar for many ethernet drivers. To simplify +code, define the helper phy_fix_phy_mode_for_mac_delays(speed, mac_txid, +mac_rxid) to fix PHY mode based on whether mac adds internal delay. + +Suggested-by: Russell King (Oracle) +Signed-off-by: Inochi Amaoto +Reviewed-by: Maxime Chevallier +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251114003805.494387-3-inochiama@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: db37c6e510de ("net: stmmac: dwmac-sophgo: Add phy interface filter") +Signed-off-by: Sasha Levin +--- + drivers/net/phy/phy-core.c | 43 ++++++++++++++++++++++++++++++++++++++ + include/linux/phy.h | 3 +++ + 2 files changed, 46 insertions(+) + +diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c +index 605ca20ae192d..0c63e6ba2cb0c 100644 +--- a/drivers/net/phy/phy-core.c ++++ b/drivers/net/phy/phy-core.c +@@ -101,6 +101,49 @@ const char *phy_rate_matching_to_str(int rate_matching) + } + EXPORT_SYMBOL_GPL(phy_rate_matching_to_str); + ++/** ++ * phy_fix_phy_mode_for_mac_delays - Convenience function for fixing PHY ++ * mode based on whether mac adds internal delay ++ * ++ * @interface: The current interface mode of the port ++ * @mac_txid: True if the mac adds internal tx delay ++ * @mac_rxid: True if the mac adds internal rx delay ++ * ++ * Return: fixed PHY mode, or PHY_INTERFACE_MODE_NA if the interface can ++ * not apply the internal delay ++ */ ++phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface, ++ bool mac_txid, bool mac_rxid) ++{ ++ if (!phy_interface_mode_is_rgmii(interface)) ++ return interface; ++ ++ if (mac_txid && mac_rxid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ if (mac_txid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII_RXID; ++ if (interface == PHY_INTERFACE_MODE_RGMII_TXID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ if (mac_rxid) { ++ if (interface == PHY_INTERFACE_MODE_RGMII_ID) ++ return PHY_INTERFACE_MODE_RGMII_TXID; ++ if (interface == PHY_INTERFACE_MODE_RGMII_RXID) ++ return PHY_INTERFACE_MODE_RGMII; ++ return PHY_INTERFACE_MODE_NA; ++ } ++ ++ return interface; ++} ++EXPORT_SYMBOL_GPL(phy_fix_phy_mode_for_mac_delays); ++ + /** + * phy_interface_num_ports - Return the number of links that can be carried by + * a given MAC-PHY physical link. Returns 0 if this is +diff --git a/include/linux/phy.h b/include/linux/phy.h +index 3c7634482356e..0bc00a4cceb24 100644 +--- a/include/linux/phy.h ++++ b/include/linux/phy.h +@@ -1813,6 +1813,9 @@ static inline bool phy_is_pseudo_fixed_link(struct phy_device *phydev) + return phydev->is_pseudo_fixed_link; + } + ++phy_interface_t phy_fix_phy_mode_for_mac_delays(phy_interface_t interface, ++ bool mac_txid, bool mac_rxid); ++ + int phy_save_page(struct phy_device *phydev); + int phy_select_page(struct phy_device *phydev, int page); + int phy_restore_page(struct phy_device *phydev, int oldpage, int ret); +-- +2.51.0 + diff --git a/queue-6.18/net-phy-adin1100-fix-software-power-down-ready-condi.patch b/queue-6.18/net-phy-adin1100-fix-software-power-down-ready-condi.patch new file mode 100644 index 0000000000..f35f168569 --- /dev/null +++ b/queue-6.18/net-phy-adin1100-fix-software-power-down-ready-condi.patch @@ -0,0 +1,54 @@ +From 16b598541d8469cf4eb93c00dcca6b3429945f49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:47:36 +0100 +Subject: net: phy: adin1100: Fix software power-down ready condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ] + +Value CRSM_SFT_PD written to Software Power-Down Control Register +(CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value +CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for +confirmation powerdown has been reached. + +The condition could have only worked when disabling powerdown +(both 0x00), but never when enabling it (0x01 != 0x02). + +Result is a timeout, like so: + + $ ifdown eth0 + macb f802c000.ethernet eth0: Link is Down + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + +Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") +Signed-off-by: Alexander Dahl +Reviewed-by: Russell King (Oracle) +Acked-by: Nuno Sá +Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/adin1100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c +index bd7a47a903aca..10b796c2daee7 100644 +--- a/drivers/net/phy/adin1100.c ++++ b/drivers/net/phy/adin1100.c +@@ -201,7 +201,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) + return ret; + + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, +- (ret & ADIN_CRSM_SFT_PD_RDY) == val, ++ !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, + 1000, 30000, true); + } + +-- +2.51.0 + diff --git a/queue-6.18/net-phy-aquantia-check-for-nvmem-deferral.patch b/queue-6.18/net-phy-aquantia-check-for-nvmem-deferral.patch new file mode 100644 index 0000000000..9466b10233 --- /dev/null +++ b/queue-6.18/net-phy-aquantia-check-for-nvmem-deferral.patch @@ -0,0 +1,41 @@ +From 00b093023881d24352e7f1f0db2336940a0afe0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 12:44:35 +0100 +Subject: net: phy: aquantia: check for NVMEM deferral + +From: Robert Marko + +[ Upstream commit a6c121a2432eee2c4ebceb1483ccd4a50a52983d ] + +Currently, if NVMEM provider is probed later than Aquantia, loading the +firmware will fail with -EINVAL. + +To fix this, simply check for -EPROBE_DEFER when NVMEM is attempted and +return it. + +Fixes: e93984ebc1c8 ("net: phy: aquantia: add firmware load support") +Signed-off-by: Robert Marko +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251127114514.460924-1-robimarko@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/aquantia/aquantia_firmware.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/aquantia/aquantia_firmware.c b/drivers/net/phy/aquantia/aquantia_firmware.c +index bbbcc9736b00e..569256152689f 100644 +--- a/drivers/net/phy/aquantia/aquantia_firmware.c ++++ b/drivers/net/phy/aquantia/aquantia_firmware.c +@@ -369,7 +369,7 @@ int aqr_firmware_load(struct phy_device *phydev) + * assume that, and load a new image. + */ + ret = aqr_firmware_load_nvmem(phydev); +- if (!ret) ++ if (ret == -EPROBE_DEFER || !ret) + return ret; + + ret = aqr_firmware_load_fs(phydev); +-- +2.51.0 + diff --git a/queue-6.18/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch b/queue-6.18/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch new file mode 100644 index 0000000000..bb63eedf3a --- /dev/null +++ b/queue-6.18/net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch @@ -0,0 +1,138 @@ +From 3680bd12c1cf994fc54b3f136657deaf7697cc78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 01:40:28 +0200 +Subject: net: phy: realtek: create rtl8211f_config_rgmii_delay() + +From: Vladimir Oltean + +[ Upstream commit 8e982441ba601d982dd0739972115d85ae01d99b ] + +The control flow in rtl8211f_config_init() has some pitfalls which were +probably unintended. Specifically it has an early return: + + switch (phydev->interface) { + ... + default: /* the rest of the modes imply leaving delay as is. */ + return 0; + } + +which exits the entire config_init() function. This means it also skips +doing things such as disabling CLKOUT or disabling PHY-mode EEE. + +For the RTL8211FS, which uses PHY_INTERFACE_MODE_SGMII, this might be a +problem. However, I don't know that it is, so there is no Fixes: tag. +The issue was observed through code inspection. + +Signed-off-by: Vladimir Oltean +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251117234033.345679-2-vladimir.oltean@nxp.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/realtek/realtek_main.c | 65 +++++++++++++++----------- + 1 file changed, 39 insertions(+), 26 deletions(-) + +diff --git a/drivers/net/phy/realtek/realtek_main.c b/drivers/net/phy/realtek/realtek_main.c +index 16a347084293e..b26f4d1c6bbfa 100644 +--- a/drivers/net/phy/realtek/realtek_main.c ++++ b/drivers/net/phy/realtek/realtek_main.c +@@ -560,22 +560,11 @@ static int rtl8211c_config_init(struct phy_device *phydev) + CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER); + } + +-static int rtl8211f_config_init(struct phy_device *phydev) ++static int rtl8211f_config_rgmii_delay(struct phy_device *phydev) + { +- struct rtl821x_priv *priv = phydev->priv; +- struct device *dev = &phydev->mdio.dev; + u16 val_txdly, val_rxdly; + int ret; + +- ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, +- RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF, +- priv->phycr1); +- if (ret < 0) { +- dev_err(dev, "aldps mode configuration failed: %pe\n", +- ERR_PTR(ret)); +- return ret; +- } +- + switch (phydev->interface) { + case PHY_INTERFACE_MODE_RGMII: + val_txdly = 0; +@@ -605,34 +594,58 @@ static int rtl8211f_config_init(struct phy_device *phydev) + RTL8211F_TXCR, RTL8211F_TX_DELAY, + val_txdly); + if (ret < 0) { +- dev_err(dev, "Failed to update the TX delay register\n"); ++ phydev_err(phydev, "Failed to update the TX delay register: %pe\n", ++ ERR_PTR(ret)); + return ret; + } else if (ret) { +- dev_dbg(dev, +- "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", +- str_enable_disable(val_txdly)); ++ phydev_dbg(phydev, ++ "%s 2ns TX delay (and changing the value from pin-strapping RXD1 or the bootloader)\n", ++ str_enable_disable(val_txdly)); + } else { +- dev_dbg(dev, +- "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", +- str_enabled_disabled(val_txdly)); ++ phydev_dbg(phydev, ++ "2ns TX delay was already %s (by pin-strapping RXD1 or bootloader configuration)\n", ++ str_enabled_disabled(val_txdly)); + } + + ret = phy_modify_paged_changed(phydev, RTL8211F_RGMII_PAGE, + RTL8211F_RXCR, RTL8211F_RX_DELAY, + val_rxdly); + if (ret < 0) { +- dev_err(dev, "Failed to update the RX delay register\n"); ++ phydev_err(phydev, "Failed to update the RX delay register: %pe\n", ++ ERR_PTR(ret)); + return ret; + } else if (ret) { +- dev_dbg(dev, +- "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n", +- str_enable_disable(val_rxdly)); ++ phydev_dbg(phydev, ++ "%s 2ns RX delay (and changing the value from pin-strapping RXD0 or the bootloader)\n", ++ str_enable_disable(val_rxdly)); + } else { +- dev_dbg(dev, +- "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n", +- str_enabled_disabled(val_rxdly)); ++ phydev_dbg(phydev, ++ "2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n", ++ str_enabled_disabled(val_rxdly)); + } + ++ return 0; ++} ++ ++static int rtl8211f_config_init(struct phy_device *phydev) ++{ ++ struct rtl821x_priv *priv = phydev->priv; ++ struct device *dev = &phydev->mdio.dev; ++ int ret; ++ ++ ret = phy_modify_paged_changed(phydev, RTL8211F_PHYCR_PAGE, RTL8211F_PHYCR1, ++ RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_XTAL_OFF, ++ priv->phycr1); ++ if (ret < 0) { ++ dev_err(dev, "aldps mode configuration failed: %pe\n", ++ ERR_PTR(ret)); ++ return ret; ++ } ++ ++ ret = rtl8211f_config_rgmii_delay(phydev); ++ if (ret) ++ return ret; ++ + if (!priv->has_phycr2) + return 0; + +-- +2.51.0 + diff --git a/queue-6.18/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-6.18/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..f52a489f97 --- /dev/null +++ b/queue-6.18/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From dae8bc9d4fad8b56b777db1bbfdc43ee3c8362d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 32bacfc314c26..d325a90cde9ee 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1597,7 +1597,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + qdisc_drop_reason(skb, sch, to_free, SKB_DROP_REASON_QDISC_OVERLIMIT); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1743,14 +1742,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1823,6 +1822,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1833,13 +1834,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1848,11 +1849,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1927,24 +1928,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch b/queue-6.18/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch new file mode 100644 index 0000000000..57e78720f4 --- /dev/null +++ b/queue-6.18/net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch @@ -0,0 +1,81 @@ +From b9502b033f5c049f71bdc5f12966d529eb0b0b74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 08:38:05 +0800 +Subject: net: stmmac: dwmac-sophgo: Add phy interface filter + +From: Inochi Amaoto + +[ Upstream commit db37c6e510deabc9b0ee27c08f1c5aaa19f2e8ef ] + +As the SG2042 has an internal rx delay, the delay should be removed +when initializing the mac, otherwise the phy will be misconfigurated. + +Fixes: 543009e2d4cd ("net: stmmac: dwmac-sophgo: Add support for Sophgo SG2042 SoC") +Signed-off-by: Inochi Amaoto +Tested-by: Han Gao +Reviewed-by: Andrew Lunn +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20251114003805.494387-4-inochiama@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../ethernet/stmicro/stmmac/dwmac-sophgo.c | 20 ++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c +index 3b7947a7a7ba7..fcdda2401968b 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c +@@ -7,11 +7,16 @@ + + #include + #include ++#include + #include + #include + + #include "stmmac_platform.h" + ++struct sophgo_dwmac_data { ++ bool has_internal_rx_delay; ++}; ++ + static int sophgo_sg2044_dwmac_init(struct platform_device *pdev, + struct plat_stmmacenet_data *plat_dat, + struct stmmac_resources *stmmac_res) +@@ -32,6 +37,7 @@ static int sophgo_sg2044_dwmac_init(struct platform_device *pdev, + static int sophgo_dwmac_probe(struct platform_device *pdev) + { + struct plat_stmmacenet_data *plat_dat; ++ const struct sophgo_dwmac_data *data; + struct stmmac_resources stmmac_res; + struct device *dev = &pdev->dev; + int ret; +@@ -50,11 +56,23 @@ static int sophgo_dwmac_probe(struct platform_device *pdev) + if (ret) + return ret; + ++ data = device_get_match_data(&pdev->dev); ++ if (data && data->has_internal_rx_delay) { ++ plat_dat->phy_interface = phy_fix_phy_mode_for_mac_delays(plat_dat->phy_interface, ++ false, true); ++ if (plat_dat->phy_interface == PHY_INTERFACE_MODE_NA) ++ return -EINVAL; ++ } ++ + return stmmac_dvr_probe(dev, plat_dat, &stmmac_res); + } + ++static const struct sophgo_dwmac_data sg2042_dwmac_data = { ++ .has_internal_rx_delay = true, ++}; ++ + static const struct of_device_id sophgo_dwmac_match[] = { +- { .compatible = "sophgo,sg2042-dwmac" }, ++ { .compatible = "sophgo,sg2042-dwmac", .data = &sg2042_dwmac_data }, + { .compatible = "sophgo,sg2044-dwmac" }, + { /* sentinel */ } + }; +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-6.18/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..e5d8fcc8b5 --- /dev/null +++ b/queue-6.18/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From 309cf071dc6bdd7a7cf3be52ea74d798f0a1400c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 7b90ecd3a55e6..86e912471dead 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5258,10 +5258,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-6.18/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch b/queue-6.18/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch new file mode 100644 index 0000000000..f8d6c68fc1 --- /dev/null +++ b/queue-6.18/net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch @@ -0,0 +1,60 @@ +From 7d489591cf66aa4462e73b8d0908e038daa9fe34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 11:27:20 +0000 +Subject: net: stmmac: Fix VLAN 0 deletion in vlan_del_hw_rx_fltr() + +From: Ovidiu Panait + +[ Upstream commit d9db25723677c3741a0cf3643f7f7429fc983921 ] + +When the "rx-vlan-filter" feature is enabled on a network device, the 8021q +module automatically adds a VLAN 0 hardware filter when the device is +brought administratively up. + +For stmmac, this causes vlan_add_hw_rx_fltr() to create a new entry for +VID 0 in the mac_device_info->vlan_filter array, in the following format: + + VLAN_TAG_DATA_ETV | VLAN_TAG_DATA_VEN | vid + +Here, VLAN_TAG_DATA_VEN indicates that the hardware filter is enabled for +that VID. + +However, on the delete path, vlan_del_hw_rx_fltr() searches the vlan_filter +array by VID only, without verifying whether a VLAN entry is enabled. As a +result, when the 8021q module attempts to remove VLAN 0, the function may +mistakenly match a zero-initialized slot rather than the actual VLAN 0 +entry, causing incorrect deletions and leaving stale entries in the +hardware table. + +Fix this by verifying that the VLAN entry's enable bit (VLAN_TAG_DATA_VEN) +is set before matching and deleting by VID. This ensures only active VLAN +entries are removed and avoids leaving stale entries in the VLAN filter +table, particularly for VLAN ID 0. + +Fixes: ed64639bc1e08 ("net: stmmac: Add support for VLAN Rx filtering") +Signed-off-by: Ovidiu Panait +Reviewed-by: Maxime Chevallier +Link: https://patch.msgid.link/20251113112721.70500-2-ovidiu.panait.rb@renesas.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +index ff02a79c00d4f..b18404dd5a8be 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_vlan.c +@@ -122,7 +122,8 @@ static int vlan_del_hw_rx_fltr(struct net_device *dev, + + /* Extended Rx VLAN Filter Enable */ + for (i = 0; i < hw->num_vlan; i++) { +- if ((hw->vlan_filter[i] & VLAN_TAG_DATA_VID) == vid) { ++ if ((hw->vlan_filter[i] & VLAN_TAG_DATA_VEN) && ++ ((hw->vlan_filter[i] & VLAN_TAG_DATA_VID) == vid)) { + ret = vlan_write_filter(dev, hw, i, 0); + + if (!ret) +-- +2.51.0 + diff --git a/queue-6.18/net-vxlan-prevent-null-deref-in-vxlan_xmit_one.patch b/queue-6.18/net-vxlan-prevent-null-deref-in-vxlan_xmit_one.patch new file mode 100644 index 0000000000..df65963145 --- /dev/null +++ b/queue-6.18/net-vxlan-prevent-null-deref-in-vxlan_xmit_one.patch @@ -0,0 +1,98 @@ +From 55292c2659a4cb999db03bd3e0810c390e7091c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:25 +0100 +Subject: net: vxlan: prevent NULL deref in vxlan_xmit_one + +From: Antoine Tenart + +[ Upstream commit 1f73a56f986005f0bc64ed23873930e2ee4f5911 ] + +Neither sock4 nor sock6 pointers are guaranteed to be non-NULL in +vxlan_xmit_one, e.g. if the iface is brought down. This can lead to the +following NULL dereference: + + BUG: kernel NULL pointer dereference, address: 0000000000000010 + Oops: Oops: 0000 [#1] SMP NOPTI + RIP: 0010:vxlan_xmit_one+0xbb3/0x1580 + Call Trace: + vxlan_xmit+0x429/0x610 + dev_hard_start_xmit+0x55/0xa0 + __dev_queue_xmit+0x6d0/0x7f0 + ip_finish_output2+0x24b/0x590 + ip_output+0x63/0x110 + +Mentioned commits changed the code path in vxlan_xmit_one and as a side +effect the sock4/6 pointer validity checks in vxlan(6)_get_route were +lost. Fix this by adding back checks. + +Since both commits being fixed were released in the same version (v6.7) +and are strongly related, bundle the fixes in a single commit. + +Reported-by: Liang Li +Fixes: 6f19b2c136d9 ("vxlan: use generic function for tunnel IPv4 route lookup") +Fixes: 2aceb896ee18 ("vxlan: use generic function for tunnel IPv6 route lookup") +Cc: Beniamino Galvani +Signed-off-by: Antoine Tenart +Reviewed-by: Ido Schimmel +Tested-by: Ido Schimmel +Link: https://patch.msgid.link/20251126102627.74223-1-atenart@kernel.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/vxlan/vxlan_core.c | 18 +++++++++++++++--- + 1 file changed, 15 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c +index a5c55e7e4d795..e957aa12a8a44 100644 +--- a/drivers/net/vxlan/vxlan_core.c ++++ b/drivers/net/vxlan/vxlan_core.c +@@ -2349,7 +2349,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + int addr_family; + __u8 tos, ttl; + int ifindex; +- int err; ++ int err = 0; + u32 flags = vxlan->cfg.flags; + bool use_cache; + bool udp_sum = false; +@@ -2454,12 +2454,18 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + + rcu_read_lock(); + if (addr_family == AF_INET) { +- struct vxlan_sock *sock4 = rcu_dereference(vxlan->vn4_sock); ++ struct vxlan_sock *sock4; + u16 ipcb_flags = 0; + struct rtable *rt; + __be16 df = 0; + __be32 saddr; + ++ sock4 = rcu_dereference(vxlan->vn4_sock); ++ if (unlikely(!sock4)) { ++ reason = SKB_DROP_REASON_DEV_READY; ++ goto tx_error; ++ } ++ + if (!ifindex) + ifindex = sock4->sock->sk->sk_bound_dev_if; + +@@ -2534,10 +2540,16 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, + ipcb_flags); + #if IS_ENABLED(CONFIG_IPV6) + } else { +- struct vxlan_sock *sock6 = rcu_dereference(vxlan->vn6_sock); ++ struct vxlan_sock *sock6; + struct in6_addr saddr; + u16 ip6cb_flags = 0; + ++ sock6 = rcu_dereference(vxlan->vn6_sock); ++ if (unlikely(!sock6)) { ++ reason = SKB_DROP_REASON_DEV_READY; ++ goto tx_error; ++ } ++ + if (!ifindex) + ifindex = sock6->sock->sk->sk_bound_dev_if; + +-- +2.51.0 + diff --git a/queue-6.18/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-6.18/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..6b675899b8 --- /dev/null +++ b/queue-6.18/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From 99dc7a5c1ceb90257136e4c34e280546b64f5aa7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 14dd1c0698c3c..e95e5f59a3d6a 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -141,12 +141,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-6.18/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-6.18/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..811363122e --- /dev/null +++ b/queue-6.18/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,503 @@ +From 8d70c68fd69286ba4787b67f7a20f2b76c28bc22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index 1b58b5b91ff6a..52a06de41aa0f 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -18,15 +18,14 @@ struct nf_conncount_list { + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen); + void nf_conncount_destroy(struct net *net, struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 913ede2f57f9a..0ffc5ff78a714 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if ((u32)jiffies == list->last_gc) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int keylen) + { +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index fc35a11cdca20..5df7134131d29 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index 0189f8b6b0bd1..848287ab79cfb 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index e573e92213029..a0811e1fba656 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -928,8 +928,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -942,8 +942,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -972,8 +973,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -1770,8 +1770,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-6.18/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-6.18/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..f256eb1d17 --- /dev/null +++ b/queue-6.18/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From ceaa31d6b9240928eb94e5a9a03835d5fe916813 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 0ffc5ff78a714..b84cfb5616df4 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if ((u32)jiffies == list->last_gc) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 5df7134131d29..d4964087bbc5e 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = READ_ONCE(priv->list->count); +-- +2.51.0 + diff --git a/queue-6.18/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-6.18/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..4caa92680f --- /dev/null +++ b/queue-6.18/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 4149e0a55f31a0f6d7ed47bc6598a49c82f4b406 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index fde5539cf6a69..425648565ab2d 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -56,7 +57,8 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-6.18/ns-add-ns_common_init.patch b/queue-6.18/ns-add-ns_common_init.patch new file mode 100644 index 0000000000..b078692e74 --- /dev/null +++ b/queue-6.18/ns-add-ns_common_init.patch @@ -0,0 +1,45 @@ +From 5029bbcaab6fabfd33891799acf0e4ca274ccab9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 16:10:10 +0100 +Subject: ns: add NS_COMMON_INIT() + +From: Christian Brauner + +[ Upstream commit d915fe20e5cba4bd50e41e792a32dcddc7490e25 ] + +Add an initializer that can be used for the ns common initialization for +static namespace such as most init namespaces. + +Suggested-by: Thomas Gleixner +Link: https://patch.msgid.link/87ecqhy2y5.ffs@tglx +Signed-off-by: Christian Brauner +Stable-dep-of: 3dd50c58664e ("ns: initialize ns_list_node for initial namespaces") +Signed-off-by: Sasha Levin +--- + include/linux/ns_common.h | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h +index f5b68b8abb543..3a72c3f81eca4 100644 +--- a/include/linux/ns_common.h ++++ b/include/linux/ns_common.h +@@ -119,6 +119,16 @@ void __ns_common_free(struct ns_common *ns); + struct user_namespace *: CLONE_NEWUSER, \ + struct uts_namespace *: CLONE_NEWUTS) + ++#define NS_COMMON_INIT(nsname, refs) \ ++{ \ ++ .ns_type = ns_common_type(&nsname), \ ++ .ns_id = 0, \ ++ .inum = ns_init_inum(&nsname), \ ++ .ops = to_ns_operations(&nsname), \ ++ .stashed = NULL, \ ++ .__ns_ref = REFCOUNT_INIT(refs), \ ++} ++ + #define ns_common_init(__ns) \ + __ns_common_init(to_ns_common(__ns), \ + ns_common_type(__ns), \ +-- +2.51.0 + diff --git a/queue-6.18/ns-initialize-ns_list_node-for-initial-namespaces.patch b/queue-6.18/ns-initialize-ns_list_node-for-initial-namespaces.patch new file mode 100644 index 0000000000..a62c1fda2f --- /dev/null +++ b/queue-6.18/ns-initialize-ns_list_node-for-initial-namespaces.patch @@ -0,0 +1,36 @@ +From 835cdc72338c49d708f1852c4f0f5e1a4d75b8a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:20:21 +0100 +Subject: ns: initialize ns_list_node for initial namespaces + +From: Christian Brauner + +[ Upstream commit 3dd50c58664e2684bd610a57bf3ab713cbb0ea91 ] + +Make sure that the list is always initialized for initial namespaces. + +Link: https://patch.msgid.link/20251029-work-namespace-nstree-listns-v4-8-2e6f823ebdc0@kernel.org +Fixes: 885fc8ac0a4d ("nstree: make iterator generic") +Tested-by: syzbot@syzkaller.appspotmail.com +Reviewed-by: Jeff Layton +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + include/linux/ns_common.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/linux/ns_common.h b/include/linux/ns_common.h +index 3a72c3f81eca4..71a5e28344d11 100644 +--- a/include/linux/ns_common.h ++++ b/include/linux/ns_common.h +@@ -127,6 +127,7 @@ void __ns_common_free(struct ns_common *ns); + .ops = to_ns_operations(&nsname), \ + .stashed = NULL, \ + .__ns_ref = REFCOUNT_INIT(refs), \ ++ .ns_list_node = LIST_HEAD_INIT(nsname.ns.ns_list_node), \ + } + + #define ns_common_init(__ns) \ +-- +2.51.0 + diff --git a/queue-6.18/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-6.18/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..5605e547b5 --- /dev/null +++ b/queue-6.18/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From f7ef2a3c65148b856e299c8b36f564129445f3e3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 3959f23c487a2..3a0676871bade 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1722,6 +1722,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-6.18/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-6.18/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..d689907ba4 --- /dev/null +++ b/queue-6.18/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From e5a4f42e8d62023ca09e3227c16b74b05f8b8899 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index c7a2f191254da..5ae910e9ecbda 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1349,7 +1349,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-6.18/ntfs3-init-run-lock-for-extend-inode.patch b/queue-6.18/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..180beec0e3 --- /dev/null +++ b/queue-6.18/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From 4d9b72825ca4fbea0c9257a9168b0b2391411247 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index 3a0676871bade..05004f8880ce6 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -472,6 +472,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-6.18/objtool-fix-standalone-hacks-jump_label.patch b/queue-6.18/objtool-fix-standalone-hacks-jump_label.patch new file mode 100644 index 0000000000..603948980b --- /dev/null +++ b/queue-6.18/objtool-fix-standalone-hacks-jump_label.patch @@ -0,0 +1,44 @@ +From e70656d7f7d436af687edd26b89b34a2b95facfa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 00:49:41 +0000 +Subject: objtool: Fix standalone --hacks=jump_label + +From: Dylan Hatch + +[ Upstream commit be8374a5ba7cbab6b97df94b4ffe0b92f5c8a6d2 ] + +The objtool command line 'objtool --hacks=jump_label foo.o' on its own +should be expected to rewrite jump labels to NOPs. This means the +add_special_section_alts() code path needs to run when only this option +is provided. + +This is mainly relevant in certain debugging situations, but could +potentially also fix kernel builds in which objtool is run with +--hacks=jump_label but without --orc, --stackval, --uaccess, or +--hacks=noinstr. + +Fixes: de6fbcedf5ab ("objtool: Read special sections with alts only when specific options are selected") +Signed-off-by: Dylan Hatch +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index 9004fbc067693..6059a546fb759 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2564,7 +2564,8 @@ static int decode_sections(struct objtool_file *file) + * Must be before add_jump_destinations(), which depends on 'func' + * being set for alternatives, to enable proper sibling call detection. + */ +- if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { ++ if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || ++ opts.hack_jump_label) { + ret = add_special_section_alts(file); + if (ret) + return ret; +-- +2.51.0 + diff --git a/queue-6.18/objtool-fix-weak-symbol-detection.patch b/queue-6.18/objtool-fix-weak-symbol-detection.patch new file mode 100644 index 0000000000..9855997539 --- /dev/null +++ b/queue-6.18/objtool-fix-weak-symbol-detection.patch @@ -0,0 +1,65 @@ +From ee08df356a51ed812f32b8bd5cec03b569ffeb0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:27 -0700 +Subject: objtool: Fix weak symbol detection + +From: Josh Poimboeuf + +[ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] + +find_symbol_hole_containing() fails to find a symbol hole (aka stripped +weak symbol) if its section has no symbols before the hole. This breaks +weak symbol detection if -ffunction-sections is enabled. + +Fix that by allowing the interval tree to contain section symbols, which +are always at offset zero for a given section. + +Fixes a bunch of (-ffunction-sections) warnings like: + + vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction + +Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") +Acked-by: Petr Mladek +Tested-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index ca5d77db692a2..9cb51fcde7986 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -108,7 +108,7 @@ struct symbol_hole { + }; + + /* +- * Find !section symbol where @offset is after it. ++ * Find the last symbol before @offset. + */ + static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + { +@@ -119,8 +119,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + return -1; + + if (sh->key >= s->offset + s->len) { +- if (s->type != STT_SECTION) +- sh->sym = s; ++ sh->sym = s; + return 1; + } + +@@ -412,7 +411,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->len = sym->sym.st_size; + + __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { +- if (iter->offset == sym->offset && iter->type == sym->type) ++ if (iter->offset == sym->offset && iter->type == sym->type && ++ iter->len == sym->len) + iter->alias = sym; + } + +-- +2.51.0 + diff --git a/queue-6.18/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-6.18/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..f8a24cf2db --- /dev/null +++ b/queue-6.18/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From 81e28d366864bb13b2539f939c7dc789a82cd106 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 10923bf7c8b84..26e150c5f25eb 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-6.18/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch b/queue-6.18/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch new file mode 100644 index 0000000000..d8cd747ff4 --- /dev/null +++ b/queue-6.18/ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch @@ -0,0 +1,54 @@ +From bcd7a1c87be2bb689b0975d84b586d2aefe06aca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 20:32:17 +0800 +Subject: ocfs2: use correct endian in ocfs2_dinode_has_extents + +From: Joseph Qi + +[ Upstream commit c9dff86eb78a4b6b02b1e407993c946ccaf9bfb4 ] + +Fields in ocfs2_dinode is little endian, covert to host endian when +checking those contents. + +Link: https://lkml.kernel.org/r/20251025123218.3997866-1-joseph.qi@linux.alibaba.com +Fixes: fdbb6cd96ed5 ("ocfs2: correct l_next_free_rec in online check") +Signed-off-by: Joseph Qi +Reviewed-by: Heming Zhao +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/inode.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c +index fcc89856ab95b..0a0a96054bfec 100644 +--- a/fs/ocfs2/inode.c ++++ b/fs/ocfs2/inode.c +@@ -201,13 +201,15 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags, + static int ocfs2_dinode_has_extents(struct ocfs2_dinode *di) + { + /* inodes flagged with other stuff in id2 */ +- if (di->i_flags & (OCFS2_SUPER_BLOCK_FL | OCFS2_LOCAL_ALLOC_FL | +- OCFS2_CHAIN_FL | OCFS2_DEALLOC_FL)) ++ if (le32_to_cpu(di->i_flags) & ++ (OCFS2_SUPER_BLOCK_FL | OCFS2_LOCAL_ALLOC_FL | OCFS2_CHAIN_FL | ++ OCFS2_DEALLOC_FL)) + return 0; + /* i_flags doesn't indicate when id2 is a fast symlink */ +- if (S_ISLNK(di->i_mode) && di->i_size && di->i_clusters == 0) ++ if (S_ISLNK(le16_to_cpu(di->i_mode)) && le64_to_cpu(di->i_size) && ++ !le32_to_cpu(di->i_clusters)) + return 0; +- if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) ++ if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) + return 0; + + return 1; +-- +2.51.0 + diff --git a/queue-6.18/of-fdt-consolidate-duplicate-code-into-helper-functi.patch b/queue-6.18/of-fdt-consolidate-duplicate-code-into-helper-functi.patch new file mode 100644 index 0000000000..7c46eadee7 --- /dev/null +++ b/queue-6.18/of-fdt-consolidate-duplicate-code-into-helper-functi.patch @@ -0,0 +1,98 @@ +From 119e18da416921615351a5e302f6a8b3525103af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:46 +0800 +Subject: of/fdt: Consolidate duplicate code into helper functions + +From: Yuntao Wang + +[ Upstream commit 8278cb72c60399f6dc6300c409879fb4c7291513 ] + +Currently, there are many pieces of nearly identical code scattered across +different places. Consolidate the duplicate code into helper functions to +improve maintainability and reduce the likelihood of errors. + +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-2-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Stable-dep-of: bec5f6092bc1 ("of/fdt: Fix the len check in early_init_dt_check_for_elfcorehdr()") +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 41 +++++++++++++++++++++++++++++++++++++++++ + include/linux/of_fdt.h | 9 +++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 0edd639898a63..0c18bdefbbeea 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -625,6 +625,47 @@ const void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + return fdt_getprop(initial_boot_params, node, name, size); + } + ++const __be32 *__init of_flat_dt_get_addr_size_prop(unsigned long node, ++ const char *name, ++ int *entries) ++{ ++ const __be32 *prop; ++ int len, elen = (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32); ++ ++ prop = of_get_flat_dt_prop(node, name, &len); ++ if (!prop || len % elen) { ++ *entries = 0; ++ return NULL; ++ } ++ ++ *entries = len / elen; ++ return prop; ++} ++ ++bool __init of_flat_dt_get_addr_size(unsigned long node, const char *name, ++ u64 *addr, u64 *size) ++{ ++ const __be32 *prop; ++ int entries; ++ ++ prop = of_flat_dt_get_addr_size_prop(node, name, &entries); ++ if (!prop || entries != 1) ++ return false; ++ ++ of_flat_dt_read_addr_size(prop, 0, addr, size); ++ return true; ++} ++ ++void __init of_flat_dt_read_addr_size(const __be32 *prop, int entry_index, ++ u64 *addr, u64 *size) ++{ ++ int entry_cells = dt_root_addr_cells + dt_root_size_cells; ++ prop += entry_cells * entry_index; ++ ++ *addr = dt_mem_next_cell(dt_root_addr_cells, &prop); ++ *size = dt_mem_next_cell(dt_root_size_cells, &prop); ++} ++ + /** + * of_fdt_is_compatible - Return true if given node from the given blob has + * compat in its compatible list +diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h +index b8d6c0c208760..51dadbaa3d63a 100644 +--- a/include/linux/of_fdt.h ++++ b/include/linux/of_fdt.h +@@ -55,6 +55,15 @@ extern int of_get_flat_dt_subnode_by_name(unsigned long node, + const char *uname); + extern const void *of_get_flat_dt_prop(unsigned long node, const char *name, + int *size); ++ ++extern const __be32 *of_flat_dt_get_addr_size_prop(unsigned long node, ++ const char *name, ++ int *entries); ++extern bool of_flat_dt_get_addr_size(unsigned long node, const char *name, ++ u64 *addr, u64 *size); ++extern void of_flat_dt_read_addr_size(const __be32 *prop, int entry_index, ++ u64 *addr, u64 *size); ++ + extern int of_flat_dt_is_compatible(unsigned long node, const char *name); + extern unsigned long of_get_flat_dt_root(void); + extern uint32_t of_get_flat_dt_phandle(unsigned long node); +-- +2.51.0 + diff --git a/queue-6.18/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch b/queue-6.18/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch new file mode 100644 index 0000000000..f14054ae67 --- /dev/null +++ b/queue-6.18/of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch @@ -0,0 +1,64 @@ +From 98a1f7e5a4881c29f6e0c113fe4de9a346a88a6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:49 +0800 +Subject: of/fdt: Fix incorrect use of dt_root_addr_cells in + early_init_dt_check_kho() + +From: Yuntao Wang + +[ Upstream commit c85da64ce2c36bba469f6feede9ca768f0361741 ] + +When reading the fdt_size value, the argument passed to dt_mem_next_cell() +is dt_root_addr_cells, but it should be dt_root_size_cells. + +The same issue occurs when reading the scratch_size value. + +Use a helper function to simplify the code and fix these issues. + +Fixes: 274cdcb1c004 ("arm64: add KHO support") +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-5-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 16 ++++------------ + 1 file changed, 4 insertions(+), 12 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index ea37ba694bcd7..fdaee4906836f 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -922,26 +922,18 @@ static void __init early_init_dt_check_kho(void) + { + unsigned long node = chosen_node_offset; + u64 fdt_start, fdt_size, scratch_start, scratch_size; +- const __be32 *p; +- int l; + + if (!IS_ENABLED(CONFIG_KEXEC_HANDOVER) || (long)node < 0) + return; + +- p = of_get_flat_dt_prop(node, "linux,kho-fdt", &l); +- if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) ++ if (!of_flat_dt_get_addr_size(node, "linux,kho-fdt", ++ &fdt_start, &fdt_size)) + return; + +- fdt_start = dt_mem_next_cell(dt_root_addr_cells, &p); +- fdt_size = dt_mem_next_cell(dt_root_addr_cells, &p); +- +- p = of_get_flat_dt_prop(node, "linux,kho-scratch", &l); +- if (l != (dt_root_addr_cells + dt_root_size_cells) * sizeof(__be32)) ++ if (!of_flat_dt_get_addr_size(node, "linux,kho-scratch", ++ &scratch_start, &scratch_size)) + return; + +- scratch_start = dt_mem_next_cell(dt_root_addr_cells, &p); +- scratch_size = dt_mem_next_cell(dt_root_addr_cells, &p); +- + kho_populate(fdt_start, fdt_size, scratch_start, scratch_size); + } + +-- +2.51.0 + diff --git a/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch b/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch new file mode 100644 index 0000000000..5f9648c47d --- /dev/null +++ b/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch @@ -0,0 +1,55 @@ +From e53a1b2afc6816d55844d6a0563879d194964ad7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:47 +0800 +Subject: of/fdt: Fix the len check in early_init_dt_check_for_elfcorehdr() + +From: Yuntao Wang + +[ Upstream commit bec5f6092bc1328895992ff02b862ba34b45a0b7 ] + +The len value is in bytes, while `dt_root_addr_cells + dt_root_size_cells` +is in cells (4 bytes per cell). Comparing them directly is incorrect. + +Use a helper function to simplify the code and address this issue. + +Fixes: f7e7ce93aac1 ("of: fdt: Add generic support for handling elf core headers property") +Fixes: e62aaeac426ab1dd ("arm64: kdump: provide /proc/vmcore file") +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-3-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 10 ++-------- + 1 file changed, 2 insertions(+), 8 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index 0c18bdefbbeea..b45f60dccd7cf 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -853,21 +853,15 @@ static void __init early_init_dt_check_for_initrd(unsigned long node) + */ + static void __init early_init_dt_check_for_elfcorehdr(unsigned long node) + { +- const __be32 *prop; +- int len; +- + if (!IS_ENABLED(CONFIG_CRASH_DUMP)) + return; + + pr_debug("Looking for elfcorehdr property... "); + +- prop = of_get_flat_dt_prop(node, "linux,elfcorehdr", &len); +- if (!prop || (len < (dt_root_addr_cells + dt_root_size_cells))) ++ if (!of_flat_dt_get_addr_size(node, "linux,elfcorehdr", ++ &elfcorehdr_addr, &elfcorehdr_size)) + return; + +- elfcorehdr_addr = dt_mem_next_cell(dt_root_addr_cells, &prop); +- elfcorehdr_size = dt_mem_next_cell(dt_root_size_cells, &prop); +- + pr_debug("elfcorehdr_start=0x%llx elfcorehdr_size=0x%llx\n", + elfcorehdr_addr, elfcorehdr_size); + } +-- +2.51.0 + diff --git a/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch-7312 b/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch-7312 new file mode 100644 index 0000000000..0f15ebc1e6 --- /dev/null +++ b/queue-6.18/of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch-7312 @@ -0,0 +1,69 @@ +From 70ad55cdaadcbcf3d4993781856b036e169e6858 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 21:47:48 +0800 +Subject: of/fdt: Fix the len check in + early_init_dt_check_for_usable_mem_range() + +From: Yuntao Wang + +[ Upstream commit 463942de13cd30fad5dba709f708483eab7efc2c ] + +The len value is in bytes, while `dt_root_addr_cells + dt_root_size_cells` +is in cells (4 bytes per cell). Modulo calculation between them is +incorrect, the units must be converted first. + +Use helper functions to simplify the code and fix this issue. + +Fixes: fb319e77a0e7 ("of: fdt: Add memory for devices by DT property "linux,usable-memory-range"") +Fixes: 2af2b50acf9b9c38 ("of: fdt: Add generic support for handling usable memory range property") +Fixes: 8f579b1c4e347b23 ("arm64: limit memory regions based on DT property, usable-memory-range") +Signed-off-by: Yuntao Wang +Link: https://patch.msgid.link/20251115134753.179931-4-yuntao.wang@linux.dev +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/fdt.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) + +diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c +index b45f60dccd7cf..ea37ba694bcd7 100644 +--- a/drivers/of/fdt.c ++++ b/drivers/of/fdt.c +@@ -884,8 +884,9 @@ static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND; + void __init early_init_dt_check_for_usable_mem_range(void) + { + struct memblock_region rgn[MAX_USABLE_RANGES] = {0}; +- const __be32 *prop, *endp; ++ const __be32 *prop; + int len, i; ++ u64 base, size; + unsigned long node = chosen_node_offset; + + if ((long)node < 0) +@@ -893,14 +894,17 @@ void __init early_init_dt_check_for_usable_mem_range(void) + + pr_debug("Looking for usable-memory-range property... "); + +- prop = of_get_flat_dt_prop(node, "linux,usable-memory-range", &len); +- if (!prop || (len % (dt_root_addr_cells + dt_root_size_cells))) ++ prop = of_flat_dt_get_addr_size_prop(node, "linux,usable-memory-range", ++ &len); ++ if (!prop) + return; + +- endp = prop + (len / sizeof(__be32)); +- for (i = 0; i < MAX_USABLE_RANGES && prop < endp; i++) { +- rgn[i].base = dt_mem_next_cell(dt_root_addr_cells, &prop); +- rgn[i].size = dt_mem_next_cell(dt_root_size_cells, &prop); ++ len = min(len, MAX_USABLE_RANGES); ++ ++ for (i = 0; i < len; i++) { ++ of_flat_dt_read_addr_size(prop, i, &base, &size); ++ rgn[i].base = base; ++ rgn[i].size = size; + + pr_debug("cap_mem_regions[%d]: base=%pa, size=%pa\n", + i, &rgn[i].base, &rgn[i].size); +-- +2.51.0 + diff --git a/queue-6.18/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch b/queue-6.18/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch new file mode 100644 index 0000000000..acffc28b0b --- /dev/null +++ b/queue-6.18/of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch @@ -0,0 +1,60 @@ +From 2b49b50a4a7ee1aa6e85605f584e0d5b6ffecea3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:04:14 -0700 +Subject: of: Skip devicetree kunit tests when RISCV+ACPI doesn't populate root + node + +From: Guenter Roeck + +[ Upstream commit 546dbb0223102813ffb5bbcb9443a47c3183f195 ] + +Starting with commit 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by +probing DT devices when ACPI is used"), riscv images no longer populate +devicetree if ACPI is enabled. This causes unit tests to fail which require +the root node to be set. + + # Subtest: of_dtb + # module: of_test + 1..2 + # of_dtb_root_node_found_by_path: EXPECTATION FAILED at drivers/of/of_test.c:21 + Expected np is not null, but is + # of_dtb_root_node_found_by_path: pass:0 fail:1 skip:0 total:1 + not ok 1 of_dtb_root_node_found_by_path + # of_dtb_root_node_populates_of_root: EXPECTATION FAILED at drivers/of/of_test.c:31 + Expected of_root is not null, but is + # of_dtb_root_node_populates_of_root: pass:0 fail:1 skip:0 total:1 + not ok 2 of_dtb_root_node_populates_of_root + +Skip those tests for RISCV if the root node is not populated. + +Fixes: 69a8b62a7aa1 ("riscv: acpi: avoid errors caused by probing DT devices when ACPI is used") +Cc: Han Gao +Cc: Paul Walmsley +Signed-off-by: Guenter Roeck +Reviewed-by: Paul Walmsley # arch/riscv +Link: https://patch.msgid.link/20251023160415.705294-1-linux@roeck-us.net +Signed-off-by: Rob Herring (Arm) +Signed-off-by: Sasha Levin +--- + drivers/of/of_kunit_helpers.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/of/of_kunit_helpers.c b/drivers/of/of_kunit_helpers.c +index 7b3ed5a382aaa..f6ed1af8b62aa 100644 +--- a/drivers/of/of_kunit_helpers.c ++++ b/drivers/of/of_kunit_helpers.c +@@ -18,8 +18,9 @@ + */ + void of_root_kunit_skip(struct kunit *test) + { +- if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root) +- kunit_skip(test, "arm64+acpi doesn't populate a root node"); ++ if ((IS_ENABLED(CONFIG_ARM64) || IS_ENABLED(CONFIG_RISCV)) && ++ IS_ENABLED(CONFIG_ACPI) && !of_root) ++ kunit_skip(test, "arm64/riscv+acpi doesn't populate a root node"); + } + EXPORT_SYMBOL_GPL(of_root_kunit_skip); + +-- +2.51.0 + diff --git a/queue-6.18/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-6.18/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..2fb8a8408a --- /dev/null +++ b/queue-6.18/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From 7336ba60b8a8423a7566f2d44ac229fcb51aaed2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index e995f692a1ecd..24bfa5231923a 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -97,7 +97,7 @@ + #define PORT_LANE_SKEW_INSERT_MASK GENMASK(23, 0) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-6.18/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch b/queue-6.18/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch new file mode 100644 index 0000000000..73d5ae2d76 --- /dev/null +++ b/queue-6.18/pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch @@ -0,0 +1,62 @@ +From feacefdf900b482d8ce54a50f78a0932fc428541 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 08:11:09 +0530 +Subject: PCI: endpoint: pci-epf-test: Fix sleeping function being called from + atomic context + +From: Bhanu Seshu Kumar Valluri + +[ Upstream commit 25423cda145f9ed6ee4a72d9f2603ac2a4685e74 ] + +When Root Complex (RC) triggers a Doorbell interrupt to Endpoint (EP), it +triggers the below warning in the EP: + + BUG: sleeping function called from invalid context at kernel/locking/mutex.c:271 + Call trace: + __might_resched+0x130/0x158 + __might_sleep+0x70/0x88 + mutex_lock+0x2c/0x80 + pci_epc_get_msi+0x78/0xd8 + pci_epf_test_raise_irq.isra.0+0x74/0x138 + pci_epf_test_doorbell_handler+0x34/0x50 + +The BUG arises because the EP's pci_epf_test_doorbell_handler() which is +running in the hard IRQ context is making an indirect call to +pci_epc_get_msi(), which uses mutex inside. + +To fix the issue, convert the hard IRQ handler to a threaded IRQ handler to +allow it to call functions that can sleep during bottom half execution. +Also, register the threaded IRQ handler with IRQF_ONESHOT to keep the +interrupt line disabled until the threaded IRQ handler completes execution. + +Fixes: eff0c286aa91 ("PCI: endpoint: pci-epf-test: Add doorbell test support") +Signed-off-by: Bhanu Seshu Kumar Valluri +[mani: reworded description a bit] +Signed-off-by: Manivannan Sadhasivam +Reviewed-by: Niklas Cassel +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20251014024109.42287-1-bhanuseshukumar@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/pci/endpoint/functions/pci-epf-test.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c +index 31617772ad516..b05e8db575c35 100644 +--- a/drivers/pci/endpoint/functions/pci-epf-test.c ++++ b/drivers/pci/endpoint/functions/pci-epf-test.c +@@ -730,8 +730,9 @@ static void pci_epf_test_enable_doorbell(struct pci_epf_test *epf_test, + if (bar < BAR_0) + goto err_doorbell_cleanup; + +- ret = request_irq(epf->db_msg[0].virq, pci_epf_test_doorbell_handler, 0, +- "pci-ep-test-doorbell", epf_test); ++ ret = request_threaded_irq(epf->db_msg[0].virq, NULL, ++ pci_epf_test_doorbell_handler, IRQF_ONESHOT, ++ "pci-ep-test-doorbell", epf_test); + if (ret) { + dev_err(&epf->dev, + "Failed to request doorbell IRQ: %d\n", +-- +2.51.0 + diff --git a/queue-6.18/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-6.18/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..84dba65424 --- /dev/null +++ b/queue-6.18/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 804416d4853fe026c1193416049ad68e8ff8ad96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index eb00aa3807220..25b8193ffbcf1 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1337,6 +1337,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-6.18/pci-prevent-resource-tree-corruption-when-bar-resize.patch b/queue-6.18/pci-prevent-resource-tree-corruption-when-bar-resize.patch new file mode 100644 index 0000000000..a4f9b6a453 --- /dev/null +++ b/queue-6.18/pci-prevent-resource-tree-corruption-when-bar-resize.patch @@ -0,0 +1,74 @@ +From 4abaa9e25d4ed841bb60614d83268c72368a87ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:26:18 +0200 +Subject: PCI: Prevent resource tree corruption when BAR resize fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 91c4c89db41499eea1b29c56655f79c3bae66e93 ] + +pbus_reassign_bridge_resources() saves bridge windows into the saved +list before attempting to adjust resource assignments to perform a BAR +resize operation. If resource adjustments cannot be completed fully, +rollback is attempted by restoring the resource from the saved list. + +The rollback, however, does not check whether the resources it restores were +assigned by the partial resize attempt. If restore changes addresses of the +resource, it can result in corrupting the resource tree. + +An example of a corrupted resource tree with overlapping addresses: + + 6200000000000-6203fbfffffff : pciex@620c3c0000000 + 6200000000000-6203fbff0ffff : PCI Bus 0030:01 + 6200020000000-62000207fffff : 0030:01:00.0 + 6200000000000-6203fbff0ffff : PCI Bus 0030:02 + +A resource that are assigned into the resource tree must remain +unchanged. Thus, release such a resource before attempting to restore +and claim it back. + +For simplicity, always do the release and claim back for the resource +even in the cases where it is restored to the same address range. + +Note: this fix may "break" some cases where devices "worked" because +the resource tree corruption allowed address space double counting to +fit more resource than what can now be assigned without double +counting. The upcoming changes to BAR resizing should address those +scenarios (to the extent possible). + +Fixes: 8bb705e3e79d ("PCI: Add pci_resize_resource() for resizing BARs") +Reported-by: Simon Richter +Link: https://lore.kernel.org/linux-pci/67840a16-99b4-4d8c-9b5c-4721ab0970a2@hogyros.de/ +Reported-by: Alex Bennée +Link: https://lore.kernel.org/linux-pci/874irqop6b.fsf@draig.linaro.org/ +Signed-off-by: Ilpo Järvinen +Signed-off-by: Bjorn Helgaas +Tested-by: Alex Bennée # AVA, AMD GPU +Link: https://patch.msgid.link/20251113162628.5946-2-ilpo.jarvinen@linux.intel.com +Signed-off-by: Sasha Levin +--- + drivers/pci/setup-bus.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c +index 3645f392a9fd3..5ba878f15db35 100644 +--- a/drivers/pci/setup-bus.c ++++ b/drivers/pci/setup-bus.c +@@ -2504,6 +2504,11 @@ int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *res) + bridge = dev_res->dev; + i = pci_resource_num(bridge, res); + ++ if (res->parent) { ++ release_child_resources(res); ++ pci_release_resource(bridge, i); ++ } ++ + restore_dev_resource(dev_res); + + pci_claim_resource(bridge, i); +-- +2.51.0 + diff --git a/queue-6.18/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch b/queue-6.18/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch new file mode 100644 index 0000000000..1d39fd8088 --- /dev/null +++ b/queue-6.18/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch @@ -0,0 +1,55 @@ +From c98d4ce260fbb79158aec1393a5d0a2943b17c36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 10:35:34 +0200 +Subject: PCI: rcar-gen2: Drop ARM dependency from PCI_RCAR_GEN2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit d312742f686582e6457070bcfd24bee8acfdf213 ] + +Since the reliance on ARM-specific struct pci_sys_data was removed, this +driver can be compile-tested on other architectures. + +While at it, make the help text a bit more generic, as some members of +the R-Car Gen2 family have a different number of internal PCI +controllers. + +Fixes: 4a957563fe0231e0 ("PCI: rcar-gen2: Convert to use modern host bridge probe functions") +Suggested-by: Ilpo Jarvinen +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: add rcar-gen2 to subject] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/00f75d6732eacce93f04ffaeedc415d2db714cd6.1759480426.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/Kconfig | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index 41748d083b933..0452151a7bccc 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -259,12 +259,11 @@ config PCIE_RCAR_EP + + config PCI_RCAR_GEN2 + bool "Renesas R-Car Gen2 Internal PCI controller" +- depends on ARCH_RENESAS || COMPILE_TEST +- depends on ARM ++ depends on (ARCH_RENESAS && ARM) || COMPILE_TEST + help + Say Y here if you want internal PCI support on R-Car Gen2 SoC. +- There are 3 internal PCI controllers available with a single +- built-in EHCI/OHCI host controller present on each one. ++ Each internal PCI controller contains a single built-in EHCI/OHCI ++ host controller. + + config PCIE_ROCKCHIP + bool +-- +2.51.0 + diff --git a/queue-6.18/pci-sg2042-fix-a-reference-count-issue-in-sg2042_pci.patch b/queue-6.18/pci-sg2042-fix-a-reference-count-issue-in-sg2042_pci.patch new file mode 100644 index 0000000000..2301a8a7fe --- /dev/null +++ b/queue-6.18/pci-sg2042-fix-a-reference-count-issue-in-sg2042_pci.patch @@ -0,0 +1,46 @@ +From 2b7d88ac9bd3f34906781efbbe138b98718ec111 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 20:13:22 +0200 +Subject: PCI: sg2042: Fix a reference count issue in sg2042_pcie_remove() + +From: Christophe JAILLET + +[ Upstream commit 932ec9dff6da40382ee63049a11a6ff047bdc259 ] + +devm_pm_runtime_enable() is used in the probe, so pm_runtime_disable() +should not be called explicitly in the remove function. + +Fixes: 1c72774df028 ("PCI: sg2042: Add Sophgo SG2042 PCIe driver") +Signed-off-by: Christophe JAILLET +Signed-off-by: Manivannan Sadhasivam +Tested-by: Chen Wang # on Pioneerbox. +Acked-by: Chen Wang +Link: https://patch.msgid.link/242eca0ff6601de7966a53706e9950fbcb10aac8.1759169586.git.christophe.jaillet@wanadoo.fr +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/cadence/pcie-sg2042.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/pci/controller/cadence/pcie-sg2042.c b/drivers/pci/controller/cadence/pcie-sg2042.c +index a077b28d48949..0c50c74d03eeb 100644 +--- a/drivers/pci/controller/cadence/pcie-sg2042.c ++++ b/drivers/pci/controller/cadence/pcie-sg2042.c +@@ -74,15 +74,12 @@ static int sg2042_pcie_probe(struct platform_device *pdev) + static void sg2042_pcie_remove(struct platform_device *pdev) + { + struct cdns_pcie *pcie = platform_get_drvdata(pdev); +- struct device *dev = &pdev->dev; + struct cdns_pcie_rc *rc; + + rc = container_of(pcie, struct cdns_pcie_rc, pcie); + cdns_pcie_host_disable(rc); + + cdns_pcie_disable_phy(pcie); +- +- pm_runtime_disable(dev); + } + + static int sg2042_pcie_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.18/pci-stm32-fix-ep-page_size-alignment.patch b/queue-6.18/pci-stm32-fix-ep-page_size-alignment.patch new file mode 100644 index 0000000000..b2f16f884c --- /dev/null +++ b/queue-6.18/pci-stm32-fix-ep-page_size-alignment.patch @@ -0,0 +1,40 @@ +From 30f5c86654f4cfcd3fc35b18251ace62b3fdeedb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 09:08:05 +0100 +Subject: PCI: stm32: Fix EP page_size alignment + +From: Christian Bruel + +[ Upstream commit ff529a9307a03ec03ed9751da053b57149300053 ] + +pci_epc_mem_alloc_addr() allocates a CPU address from the ATU window phys +base and a page number. Set the ep->page_size so the resulting CPU address +is correctly aligned with the ATU required alignment. + +Fixes: 151f3d29baf4 ("PCI: stm32-ep: Add PCIe Endpoint support for STM32MP25") +Signed-off-by: Christian Bruel +[mani: added fixes tag] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251114-atu_align_ep-v1-1-88da5366fa04@foss.st.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-stm32-ep.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pcie-stm32-ep.c b/drivers/pci/controller/dwc/pcie-stm32-ep.c +index faa6433a784f3..7d48038d576d9 100644 +--- a/drivers/pci/controller/dwc/pcie-stm32-ep.c ++++ b/drivers/pci/controller/dwc/pcie-stm32-ep.c +@@ -214,6 +214,8 @@ static int stm32_add_pcie_ep(struct stm32_pcie *stm32_pcie, + + ep->ops = &stm32_pcie_ep_ops; + ++ ep->page_size = stm32_pcie_epc_features.align; ++ + ret = dw_pcie_ep_init(ep); + if (ret) { + dev_err(dev, "Failed to initialize ep: %d\n", ret); +-- +2.51.0 + diff --git a/queue-6.18/pci-stm32-fix-ltssm-ep-race-with-start-link.patch b/queue-6.18/pci-stm32-fix-ltssm-ep-race-with-start-link.patch new file mode 100644 index 0000000000..22167590f3 --- /dev/null +++ b/queue-6.18/pci-stm32-fix-ltssm-ep-race-with-start-link.patch @@ -0,0 +1,107 @@ +From a374fb894c82d02cca4fd15dbf42e544a3279ff8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 08:45:52 +0100 +Subject: PCI: stm32: Fix LTSSM EP race with start link + +From: Christian Bruel + +[ Upstream commit fa81d6099007728cae39c6f937d83903bbddab5e ] + +If the host has deasserted PERST# and started link training before the link +is started on EP side, enabling LTSSM before the endpoint registers are +initialized in the perst_irq handler results in probing incorrect values. + +Thus, wait for the PERST# level-triggered interrupt to start link training +at the end of initialization and cleanup the stm32_pcie_[start stop]_link +functions. + +Fixes: 151f3d29baf4 ("PCI: stm32-ep: Add PCIe Endpoint support for STM32MP25") +Signed-off-by: Christian Bruel +[mani: added fixes tag] +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: wrap line] +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251114-perst_ep-v1-1-e7976317a890@foss.st.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-stm32-ep.c | 39 +++++----------------- + 1 file changed, 8 insertions(+), 31 deletions(-) + +diff --git a/drivers/pci/controller/dwc/pcie-stm32-ep.c b/drivers/pci/controller/dwc/pcie-stm32-ep.c +index 3400c7cd2d88a..faa6433a784f3 100644 +--- a/drivers/pci/controller/dwc/pcie-stm32-ep.c ++++ b/drivers/pci/controller/dwc/pcie-stm32-ep.c +@@ -37,36 +37,9 @@ static void stm32_pcie_ep_init(struct dw_pcie_ep *ep) + dw_pcie_ep_reset_bar(pci, bar); + } + +-static int stm32_pcie_enable_link(struct dw_pcie *pci) +-{ +- struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); +- +- regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, +- STM32MP25_PCIECR_LTSSM_EN, +- STM32MP25_PCIECR_LTSSM_EN); +- +- return dw_pcie_wait_for_link(pci); +-} +- +-static void stm32_pcie_disable_link(struct dw_pcie *pci) +-{ +- struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); +- +- regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, STM32MP25_PCIECR_LTSSM_EN, 0); +-} +- + static int stm32_pcie_start_link(struct dw_pcie *pci) + { + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); +- int ret; +- +- dev_dbg(pci->dev, "Enable link\n"); +- +- ret = stm32_pcie_enable_link(pci); +- if (ret) { +- dev_err(pci->dev, "PCIe cannot establish link: %d\n", ret); +- return ret; +- } + + enable_irq(stm32_pcie->perst_irq); + +@@ -77,11 +50,7 @@ static void stm32_pcie_stop_link(struct dw_pcie *pci) + { + struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci); + +- dev_dbg(pci->dev, "Disable link\n"); +- + disable_irq(stm32_pcie->perst_irq); +- +- stm32_pcie_disable_link(pci); + } + + static int stm32_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no, +@@ -152,6 +121,9 @@ static void stm32_pcie_perst_assert(struct dw_pcie *pci) + + dev_dbg(dev, "PERST asserted by host\n"); + ++ regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, ++ STM32MP25_PCIECR_LTSSM_EN, 0); ++ + pci_epc_deinit_notify(ep->epc); + + stm32_pcie_disable_resources(stm32_pcie); +@@ -192,6 +164,11 @@ static void stm32_pcie_perst_deassert(struct dw_pcie *pci) + + pci_epc_init_notify(ep->epc); + ++ /* Enable link training */ ++ regmap_update_bits(stm32_pcie->regmap, SYSCFG_PCIECR, ++ STM32MP25_PCIECR_LTSSM_EN, ++ STM32MP25_PCIECR_LTSSM_EN); ++ + return; + + err_disable_resources: +-- +2.51.0 + diff --git a/queue-6.18/perf-annotate-check-return-value-of-evsel__get_arch-.patch b/queue-6.18/perf-annotate-check-return-value-of-evsel__get_arch-.patch new file mode 100644 index 0000000000..4552021c0c --- /dev/null +++ b/queue-6.18/perf-annotate-check-return-value-of-evsel__get_arch-.patch @@ -0,0 +1,39 @@ +From 3123f793a9f458319e877e62d2b2dea3d7a328a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 15:30:05 +0800 +Subject: perf annotate: Check return value of evsel__get_arch() properly + +From: Tianyou Li + +[ Upstream commit f1204e5846d22fb2fffbd1164eeb19535f306797 ] + +Check the error code of evsel__get_arch() in the symbol__annotate(). +Previously it checked non-zero value but after the refactoring it does +only for negative values. + +Fixes: 0669729eb0afb0cf ("perf annotate: Factor out evsel__get_arch()") +Suggested-by: James Clark +Acked-by: Namhyung Kim +Signed-off-by: Tianyou Li +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/annotate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c +index a2e34f149a074..1d6900033b3a0 100644 +--- a/tools/perf/util/annotate.c ++++ b/tools/perf/util/annotate.c +@@ -1021,7 +1021,7 @@ int symbol__annotate(struct map_symbol *ms, struct evsel *evsel, + int err, nr; + + err = evsel__get_arch(evsel, &arch); +- if (err < 0) ++ if (err) + return err; + + if (parch) +-- +2.51.0 + diff --git a/queue-6.18/perf-annotate-fix-build-with-no_slang-1.patch b/queue-6.18/perf-annotate-fix-build-with-no_slang-1.patch new file mode 100644 index 0000000000..d4a9873cec --- /dev/null +++ b/queue-6.18/perf-annotate-fix-build-with-no_slang-1.patch @@ -0,0 +1,74 @@ +From fb2c09a6a909f2ff6119cd5f5708ce3b637f3c74 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 12:07:50 +0900 +Subject: perf annotate: Fix build with NO_SLANG=1 + +From: Namhyung Kim + +[ Upstream commit 0e6c07a3c30cdc4509fc5e7dc490d4cc6e5c241a ] + +The recent change for perf c2c annotate broke build without slang +support like below. + + builtin-annotate.c: In function 'hists__find_annotations': + builtin-annotate.c:522:73: error: 'NO_ADDR' undeclared (first use in this function); did you mean 'NR_ADDR'? + 522 | key = hist_entry__tui_annotate(he, evsel, NULL, NO_ADDR); + | ^~~~~~~ + | NR_ADDR + builtin-annotate.c:522:73: note: each undeclared identifier is reported only once for each function it appears in + + builtin-annotate.c:522:31: error: too many arguments to function 'hist_entry__tui_annotate' + 522 | key = hist_entry__tui_annotate(he, evsel, NULL, NO_ADDR); + | ^~~~~~~~~~~~~~~~~~~~~~~~ + In file included from util/sort.h:6, + from builtin-annotate.c:28: + util/hist.h:756:19: note: declared here + 756 | static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, + | ^~~~~~~~~~~~~~~~~~~~~~~~ + +And I noticed that it missed to update the other side of #ifdef +HAVE_SLANG_SUPPORT. Let's fix it. + +Cc: Tianyou Li +Fixes: cd3466cd2639783d ("perf c2c: Add annotation support to perf c2c report") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hist.h | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h +index c64005278687c..a4f244a046866 100644 +--- a/tools/perf/util/hist.h ++++ b/tools/perf/util/hist.h +@@ -709,6 +709,8 @@ struct block_hist { + struct hist_entry he; + }; + ++#define NO_ADDR 0 ++ + #ifdef HAVE_SLANG_SUPPORT + #include "../ui/keysyms.h" + void attr_to_script(char *buf, struct perf_event_attr *attr); +@@ -746,14 +748,16 @@ int evlist__tui_browse_hists(struct evlist *evlist __maybe_unused, + static inline int __hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, + struct map_symbol *ms __maybe_unused, + struct evsel *evsel __maybe_unused, +- struct hist_browser_timer *hbt __maybe_unused) ++ struct hist_browser_timer *hbt __maybe_unused, ++ u64 al_addr __maybe_unused) + { + return 0; + } + + static inline int hist_entry__tui_annotate(struct hist_entry *he __maybe_unused, + struct evsel *evsel __maybe_unused, +- struct hist_browser_timer *hbt __maybe_unused) ++ struct hist_browser_timer *hbt __maybe_unused, ++ u64 al_addr __maybe_unused) + { + return 0; + } +-- +2.51.0 + diff --git a/queue-6.18/perf-arm_spe-fix-memset-subclass-in-operation.patch b/queue-6.18/perf-arm_spe-fix-memset-subclass-in-operation.patch new file mode 100644 index 0000000000..3c2bc3157b --- /dev/null +++ b/queue-6.18/perf-arm_spe-fix-memset-subclass-in-operation.patch @@ -0,0 +1,99 @@ +From 2dedc7cd2f5623484228daaca804f430fee28b03 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 18:24:27 +0000 +Subject: perf arm_spe: Fix memset subclass in operation + +From: Leo Yan + +[ Upstream commit 33e1fffea492b7158a168914dc0da6aedf78d08e ] + +The operation subclass is extracted from bits [7..1] of the payload. +Since bit [0] is not parsed, there is no chance to match the memset type +(0x25). As a result, the memset payload is never parsed successfully. + +Instead of extracting a unified bit field, change to extract the +specific bits for each operation subclass. + +Fixes: 34fb60400e32 ("perf arm-spe: Add raw decoding for SPEv1.3 MTE and MOPS load/store") +Signed-off-by: Leo Yan +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 ++++++------------- + .../arm-spe-decoder/arm-spe-pkt-decoder.h | 15 ++++++----- + 2 files changed, 14 insertions(+), 26 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index 80561630253dd..1a1ffe50ee73a 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -371,31 +371,20 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR"); + } + +- switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) { +- case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP: ++ if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_GP_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMSET: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET"); +- break; +- default: +- break; +- } + + if (SPE_OP_PKT_IS_LDST_SVE(payload)) { + /* SVE effective vector length */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index d00c2481712dc..75e355fe3438c 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -125,14 +125,13 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) +-#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 +-#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +-#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10 +-#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30 +-#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG 0x14 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY 0x20 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET 0x25 ++#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x0) ++#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(v) (((v) & GENMASK_ULL(7, 1)) == 0x4) ++#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x10) ++#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(v) (((v) & GENMASK_ULL(7, 1)) == 0x30) ++#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(v) (((v) & GENMASK_ULL(7, 1)) == 0x14) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(v) (((v) & GENMASK_ULL(7, 1)) == 0x20) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET(v) (((v) & GENMASK_ULL(7, 0)) == 0x25) + + #define SPE_OP_PKT_IS_LDST_ATOMIC(v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2) + +-- +2.51.0 + diff --git a/queue-6.18/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch b/queue-6.18/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch new file mode 100644 index 0000000000..20671f13b8 --- /dev/null +++ b/queue-6.18/perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch @@ -0,0 +1,84 @@ +From 5312cab62428cefc11401504f3d4fb3106a6dc5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 06:29:11 -0700 +Subject: perf bpf_counter: Fix opening of "any"(-1) CPU events + +From: Ian Rogers + +[ Upstream commit 2a67955de13624ec17d1c2504d2c9eeb37933b77 ] + +The bperf BPF counter code doesn't handle "any"(-1) CPU events, always +wanting to aggregate a count against a CPU, which avoids the need for +atomics so let's not change that. Force evsels used for BPF counters +to require a CPU when not in system-wide mode so that the "any"(-1) +value isn't used during map propagation and evsel's CPU map matches +that of the PMU. + +Fixes: b91917c0c6fa ("perf bpf_counter: Fix handling of cpumap fixing hybrid") +Signed-off-by: Ian Rogers +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-stat.c | 13 +++++++++++++ + tools/perf/util/bpf_counter.c | 7 ++++++- + 2 files changed, 19 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c +index 7006f848f87a6..f1c9d6c94fc50 100644 +--- a/tools/perf/builtin-stat.c ++++ b/tools/perf/builtin-stat.c +@@ -2540,6 +2540,7 @@ int cmd_stat(int argc, const char **argv) + unsigned int interval, timeout; + const char * const stat_subcommands[] = { "record", "report" }; + char errbuf[BUFSIZ]; ++ struct evsel *counter; + + setlocale(LC_ALL, ""); + +@@ -2797,6 +2798,18 @@ int cmd_stat(int argc, const char **argv) + + evlist__warn_user_requested_cpus(evsel_list, target.cpu_list); + ++ evlist__for_each_entry(evsel_list, counter) { ++ /* ++ * Setup BPF counters to require CPUs as any(-1) isn't ++ * supported. evlist__create_maps below will propagate this ++ * information to the evsels. Note, evsel__is_bperf isn't yet ++ * set up, and this change must happen early, so directly use ++ * the bpf_counter variable and target information. ++ */ ++ if ((counter->bpf_counter || target.use_bpf) && !target__has_cpu(&target)) ++ counter->core.requires_cpu = true; ++ } ++ + if (evlist__create_maps(evsel_list, &target) < 0) { + if (target__has_task(&target)) { + pr_err("Problems finding threads of monitor\n"); +diff --git a/tools/perf/util/bpf_counter.c b/tools/perf/util/bpf_counter.c +index ca5d01b9017db..a5882b5822057 100644 +--- a/tools/perf/util/bpf_counter.c ++++ b/tools/perf/util/bpf_counter.c +@@ -460,6 +460,7 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd, + struct bperf_leader_bpf *skel = bperf_leader_bpf__open(); + int link_fd, diff_map_fd, err; + struct bpf_link *link = NULL; ++ struct perf_thread_map *threads; + + if (!skel) { + pr_err("Failed to open leader skeleton\n"); +@@ -495,7 +496,11 @@ static int bperf_reload_leader_program(struct evsel *evsel, int attr_map_fd, + * following evsel__open_per_cpu call + */ + evsel->leader_skel = skel; +- evsel__open(evsel, evsel->core.cpus, evsel->core.threads); ++ assert(!perf_cpu_map__has_any_cpu_or_is_empty(evsel->core.cpus)); ++ /* Always open system wide. */ ++ threads = thread_map__new_by_tid(-1); ++ evsel__open(evsel, evsel->core.cpus, threads); ++ perf_thread_map__put(threads); + + out: + bperf_leader_bpf__destroy(skel); +-- +2.51.0 + diff --git a/queue-6.18/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch b/queue-6.18/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch new file mode 100644 index 0000000000..5a387f92c1 --- /dev/null +++ b/queue-6.18/perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch @@ -0,0 +1,42 @@ +From cefef821628bcddada294dd547821597e8752da3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 00:19:18 -0800 +Subject: perf hist: In init, ensure mem_info is put on error paths + +From: Ian Rogers + +[ Upstream commit f60efb4454b24cc944ff3eac164bb9dce9169f71 ] + +Rather than exit the internal map_symbols directly, put the mem-info +that does this and also lowers the reference count on the mem-info +itself otherwise the mem-info is being leaked. + +Fixes: 56e144fe98260a0f ("perf mem_info: Add and use map_symbol__exit and addr_map_symbol__exit") +Signed-off-by: Ian Rogers +Reviewed-by: Arnaldo Carvalho de Melo +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hist.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c +index 64ff427040c34..ef4b569f7df46 100644 +--- a/tools/perf/util/hist.c ++++ b/tools/perf/util/hist.c +@@ -608,10 +608,8 @@ static int hist_entry__init(struct hist_entry *he, + map_symbol__exit(&he->branch_info->to.ms); + zfree(&he->branch_info); + } +- if (he->mem_info) { +- map_symbol__exit(&mem_info__iaddr(he->mem_info)->ms); +- map_symbol__exit(&mem_info__daddr(he->mem_info)->ms); +- } ++ if (he->mem_info) ++ mem_info__zput(he->mem_info); + err: + map_symbol__exit(&he->ms); + zfree(&he->stat_acc); +-- +2.51.0 + diff --git a/queue-6.18/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch b/queue-6.18/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch new file mode 100644 index 0000000000..c582af7a1b --- /dev/null +++ b/queue-6.18/perf-hwmon_pmu-fix-uninitialized-variable-warning.patch @@ -0,0 +1,46 @@ +From 8cd011212869da4cd0502a3532e0eeb6823c06ce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 12:38:35 +0200 +Subject: perf hwmon_pmu: Fix uninitialized variable warning +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Suchanek + +[ Upstream commit 2fee899c068c159e486e62623afe9e2a4975bd79 ] + +The line_len is only set on success. Check the return value instead. + + util/hwmon_pmu.c: In function ‘perf_pmus__read_hwmon_pmus’: + util/hwmon_pmu.c:742:20: warning: ‘line_len’ may be used uninitialized [-Wmaybe-uninitialized] + 742 | if (line_len > 0 && line[line_len - 1] == '\n') + | ^ + util/hwmon_pmu.c:719:24: note: ‘line_len’ was declared here + 719 | size_t line_len; + +Fixes: 53cc0b351ec9 ("perf hwmon_pmu: Add a tool PMU exposing events from hwmon in sysfs") +Signed-off-by: Michal Suchanek +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/hwmon_pmu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/tools/perf/util/hwmon_pmu.c b/tools/perf/util/hwmon_pmu.c +index 416dfea9ffff6..5c27256a220a5 100644 +--- a/tools/perf/util/hwmon_pmu.c ++++ b/tools/perf/util/hwmon_pmu.c +@@ -742,8 +742,7 @@ int perf_pmus__read_hwmon_pmus(struct list_head *pmus) + continue; + } + io__init(&io, name_fd, buf2, sizeof(buf2)); +- io__getline(&io, &line, &line_len); +- if (line_len > 0 && line[line_len - 1] == '\n') ++ if (io__getline(&io, &line, &line_len) > 0 && line[line_len - 1] == '\n') + line[line_len - 1] = '\0'; + hwmon_pmu__new(pmus, buf, class_hwmon_ent->d_name, line); + close(name_fd); +-- +2.51.0 + diff --git a/queue-6.18/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch b/queue-6.18/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch new file mode 100644 index 0000000000..413443a89a --- /dev/null +++ b/queue-6.18/perf-jitdump-add-sym-str-tables-to-build-id-generati.patch @@ -0,0 +1,122 @@ +From 8bb865d7bdca337db3083086d6b788de12c3b2db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 00:07:46 -0800 +Subject: perf jitdump: Add sym/str-tables to build-ID generation + +From: Namhyung Kim + +[ Upstream commit 25d498e636d1f8d138d65246cfb5b1fc3069ca56 ] + +It was reported that python backtrace with JIT dump was broken after the +change to built-in SHA-1 implementation. It seems python generates the +same JIT code for each function. They will become separate DSOs but the +contents are the same. Only difference is in the symbol name. + +But this caused a problem that every JIT'ed DSOs will have the same +build-ID which makes perf confused. And it resulted in no python +symbols (from JIT) in the output. + +Looking back at the original code before the conversion, it used the +load_addr as well as the code section to distinguish each DSO. But it'd +be better to use contents of symtab and strtab instead as it aligns with +some linker behaviors. + +This patch adds a buffer to save all the contents in a single place for +SHA-1 calculation. Probably we need to add sha1_update() or similar to +update the existing hash value with different contents and use it here. +But it's out of scope for this change and I'd like something that can be +backported to the stable trees easily. + +Reviewed-by: Ian Rogers +Cc: Eric Biggers +Cc: Pablo Galindo +Cc: Fangrui Song +Link: https://github.com/python/cpython/issues/139544 +Fixes: e3f612c1d8f3945b ("perf genelf: Remove libcrypto dependency and use built-in sha1()") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/genelf.c | 32 ++++++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/genelf.c b/tools/perf/util/genelf.c +index 591548b10e34e..a1cd5196f4ec8 100644 +--- a/tools/perf/util/genelf.c ++++ b/tools/perf/util/genelf.c +@@ -173,6 +173,8 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + Elf_Shdr *shdr; + uint64_t eh_frame_base_offset; + char *strsym = NULL; ++ void *build_id_data = NULL, *tmp; ++ int build_id_data_len; + int symlen; + int retval = -1; + +@@ -251,6 +253,14 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_flags = SHF_EXECINSTR | SHF_ALLOC; + shdr->sh_entsize = 0; + ++ build_id_data = malloc(csize); ++ if (build_id_data == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(build_id_data, code, csize); ++ build_id_data_len = csize; ++ + /* + * Setup .eh_frame_hdr and .eh_frame + */ +@@ -334,6 +344,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_entsize = sizeof(Elf_Sym); + shdr->sh_link = unwinding ? 6 : 4; /* index of .strtab section */ + ++ tmp = realloc(build_id_data, build_id_data_len + sizeof(symtab)); ++ if (tmp == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(tmp + build_id_data_len, symtab, sizeof(symtab)); ++ build_id_data = tmp; ++ build_id_data_len += sizeof(symtab); ++ + /* + * setup symbols string table + * 2 = 1 for 0 in 1st entry, 1 for the 0 at end of symbol for 2nd entry +@@ -376,6 +395,15 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + shdr->sh_flags = 0; + shdr->sh_entsize = 0; + ++ tmp = realloc(build_id_data, build_id_data_len + symlen); ++ if (tmp == NULL) { ++ warnx("cannot allocate build-id data"); ++ goto error; ++ } ++ memcpy(tmp + build_id_data_len, strsym, symlen); ++ build_id_data = tmp; ++ build_id_data_len += symlen; ++ + /* + * setup build-id section + */ +@@ -394,7 +422,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + /* + * build-id generation + */ +- sha1(code, csize, bnote.build_id); ++ sha1(build_id_data, build_id_data_len, bnote.build_id); + bnote.desc.namesz = sizeof(bnote.name); /* must include 0 termination */ + bnote.desc.descsz = sizeof(bnote.build_id); + bnote.desc.type = NT_GNU_BUILD_ID; +@@ -439,7 +467,7 @@ jit_write_elf(int fd, uint64_t load_addr __maybe_unused, const char *sym, + (void)elf_end(e); + + free(strsym); +- ++ free(build_id_data); + + return retval; + } +-- +2.51.0 + diff --git a/queue-6.18/perf-kvm-fix-debug-assertion.patch b/queue-6.18/perf-kvm-fix-debug-assertion.patch new file mode 100644 index 0000000000..e91e68a9a7 --- /dev/null +++ b/queue-6.18/perf-kvm-fix-debug-assertion.patch @@ -0,0 +1,37 @@ +From be0c1dd80156ee5e58c8e9171e7dd706390e0ec2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 00:19:13 -0800 +Subject: perf kvm: Fix debug assertion + +From: Ian Rogers + +[ Upstream commit 27e711257902475097dea3f79cbdf241fe37ec00 ] + +There are 2 slots left for kvm_add_default_arch_event, fix the +assertion so that debug builds don't fail the assert and to agree with +the comment. + +Fixes: 45ff39f6e70aa55d0 ("perf tools kvm: Fix the potential out of range memory access issue") +Signed-off-by: Ian Rogers +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-kvm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c +index f0f285763f190..c61369d54dd9d 100644 +--- a/tools/perf/builtin-kvm.c ++++ b/tools/perf/builtin-kvm.c +@@ -2014,7 +2014,7 @@ static int __cmd_record(const char *file_name, int argc, const char **argv) + for (j = 1; j < argc; j++, i++) + rec_argv[i] = STRDUP_FAIL_EXIT(argv[j]); + +- BUG_ON(i != rec_argc); ++ BUG_ON(i + 2 != rec_argc); + + ret = kvm_add_default_arch_event(&i, rec_argv); + if (ret) +-- +2.51.0 + diff --git a/queue-6.18/perf-lock-contention-load-kernel-map-before-lookup.patch b/queue-6.18/perf-lock-contention-load-kernel-map-before-lookup.patch new file mode 100644 index 0000000000..11207bac1c --- /dev/null +++ b/queue-6.18/perf-lock-contention-load-kernel-map-before-lookup.patch @@ -0,0 +1,56 @@ +From 54350dd55ec9cd52aa0ccbe3b541eafa3f96a2e6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 21:01:39 -0700 +Subject: perf lock contention: Load kernel map before lookup + +From: Namhyung Kim + +[ Upstream commit 553d18c98a896094b99a01765b9698b204183d49 ] + +On some machines, it caused troubles when it tried to find kernel +symbols. I think it's because kernel modules and kallsyms are messed +up during load and split. + +Basically we want to make sure the kernel map is loaded and the code has +it in the lock_contention_read(). But recently we added more lookups in +the lock_contention_prepare() which is called before _read(). + +Also the kernel map (kallsyms) may not be the first one in the group +like on ARM. Let's use machine__kernel_map() rather than just loading +the first map. + +Reviewed-by: Ian Rogers +Fixes: 688d2e8de231c54e ("perf lock contention: Add -l/--lock-addr option") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_lock_contention.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c +index 60b81d586323f..7b5671f13c535 100644 +--- a/tools/perf/util/bpf_lock_contention.c ++++ b/tools/perf/util/bpf_lock_contention.c +@@ -184,6 +184,9 @@ int lock_contention_prepare(struct lock_contention *con) + struct evlist *evlist = con->evlist; + struct target *target = con->target; + ++ /* make sure it loads the kernel map before lookup */ ++ map__load(machine__kernel_map(con->machine)); ++ + skel = lock_contention_bpf__open(); + if (!skel) { + pr_err("Failed to open lock-contention BPF skeleton\n"); +@@ -749,9 +752,6 @@ int lock_contention_read(struct lock_contention *con) + bpf_prog_test_run_opts(prog_fd, &opts); + } + +- /* make sure it loads the kernel map */ +- maps__load_first(machine->kmaps); +- + prev_key = NULL; + while (!bpf_map_get_next_key(fd, prev_key, &key)) { + s64 ls_key; +-- +2.51.0 + diff --git a/queue-6.18/perf-parse-events-fix-legacy-cache-events-if-event-i.patch b/queue-6.18/perf-parse-events-fix-legacy-cache-events-if-event-i.patch new file mode 100644 index 0000000000..1c082379f5 --- /dev/null +++ b/queue-6.18/perf-parse-events-fix-legacy-cache-events-if-event-i.patch @@ -0,0 +1,111 @@ +From f32d7ffb3e71134d3c57d948a63ae22d98c310d9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 5 Oct 2025 11:24:04 -0700 +Subject: perf parse-events: Fix legacy cache events if event is duplicated in + a PMU + +From: Ian Rogers + +[ Upstream commit b7b76f607a15f16031001687e733046b5f6f5d86 ] + +The term list when adding an event to a PMU is expected to have the +event name for the alias lookup. Also, set found_supported so that +-EINVAL isn't returned. + +Fixes: 62593394f66a ("perf parse-events: Legacy cache names on all +PMUs and lower priority") + +Tested-by: Thomas Richter +Signed-off-by: Ian Rogers +Tested-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events.c | 28 +++++++++++++++++++++++++++- + tools/perf/util/parse-events.h | 3 ++- + tools/perf/util/parse-events.y | 2 +- + 3 files changed, 30 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index da73d686f6b93..90a765016f64f 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -475,8 +475,10 @@ static int parse_events_add_pmu(struct parse_events_state *parse_state, + + int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + struct parse_events_state *parse_state, +- struct parse_events_terms *parsed_terms) ++ struct parse_events_terms *parsed_terms, ++ void *loc_) + { ++ YYLTYPE *loc = loc_; + struct perf_pmu *pmu = NULL; + bool found_supported = false; + const char *config_name = get_config_name(parsed_terms); +@@ -497,12 +499,36 @@ int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + * The PMU has the event so add as not a legacy cache + * event. + */ ++ struct parse_events_terms temp_terms; ++ struct parse_events_term *term; ++ char *config = strdup(name); ++ ++ if (!config) ++ goto out_err; ++ ++ parse_events_terms__init(&temp_terms); ++ if (!parsed_terms) ++ parsed_terms = &temp_terms; ++ ++ if (parse_events_term__num(&term, ++ PARSE_EVENTS__TERM_TYPE_USER, ++ config, /*num=*/1, /*novalue=*/true, ++ loc, /*loc_val=*/NULL) < 0) { ++ zfree(&config); ++ goto out_err; ++ } ++ list_add(&term->list, &parsed_terms->terms); ++ + ret = parse_events_add_pmu(parse_state, list, pmu, + parsed_terms, + first_wildcard_match, + /*alternate_hw_config=*/PERF_COUNT_HW_MAX); ++ list_del_init(&term->list); ++ parse_events_term__delete(term); ++ parse_events_terms__exit(&temp_terms); + if (ret) + goto out_err; ++ found_supported = true; + if (first_wildcard_match == NULL) + first_wildcard_match = + container_of(list->prev, struct evsel, core.node); +diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h +index 8f8c8e7fbcf18..8af19dec6a17d 100644 +--- a/tools/perf/util/parse-events.h ++++ b/tools/perf/util/parse-events.h +@@ -237,7 +237,8 @@ int parse_events_add_numeric(struct parse_events_state *parse_state, + bool wildcard); + int parse_events_add_cache(struct list_head *list, int *idx, const char *name, + struct parse_events_state *parse_state, +- struct parse_events_terms *parsed_terms); ++ struct parse_events_terms *parsed_terms, ++ void *loc); + int parse_events__decode_legacy_cache(const char *name, int pmu_type, __u64 *config); + int parse_events_add_breakpoint(struct parse_events_state *parse_state, + struct list_head *list, +diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y +index a2361c0040d75..ced26c549c33a 100644 +--- a/tools/perf/util/parse-events.y ++++ b/tools/perf/util/parse-events.y +@@ -353,7 +353,7 @@ PE_LEGACY_CACHE opt_event_config + if (!list) + YYNOMEM; + +- err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2); ++ err = parse_events_add_cache(list, &parse_state->idx, $1, parse_state, $2, &@1); + + parse_events_terms__delete($2); + free($1); +-- +2.51.0 + diff --git a/queue-6.18/perf-parse-events-make-x-modifier-more-respectful-of.patch b/queue-6.18/perf-parse-events-make-x-modifier-more-respectful-of.patch new file mode 100644 index 0000000000..b9ef14612d --- /dev/null +++ b/queue-6.18/perf-parse-events-make-x-modifier-more-respectful-of.patch @@ -0,0 +1,102 @@ +From 7ebb69abe593aaa930e6fd45380b76017c62ace0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 16:03:57 -0700 +Subject: perf parse-events: Make X modifier more respectful of groups + +From: Ian Rogers + +[ Upstream commit 800201997a509c298e74696da3586d82b1a2b6f4 ] + +Events with an X modifier were reordered within a group, for example +slots was made the leader in: +``` +$ perf record -e '{cpu/mem-stores/ppu,cpu/slots/uX}' -- sleep 1 +``` + +Fix by making `dont_regroup` evsels always use their index for +sorting. Make the cur_leader, when fixing the groups, be that of +`dont_regroup` evsel so that the `dont_regroup` evsel doesn't become a +leader. + +On a tigerlake this patch corrects this and meets expectations in: +``` +$ perf stat -e '{cpu/mem-stores/,cpu/slots/uX}' -a -- sleep 0.1 + + Performance counter stats for 'system wide': + + 83,458,652 cpu/mem-stores/ + 2,720,854,880 cpu/slots/uX + + 0.103780587 seconds time elapsed + +$ perf stat -e 'slots,slots:X' -a -- sleep 0.1 + + Performance counter stats for 'system wide': + + 732,042,247 slots (48.96%) + 643,288,155 slots:X (51.04%) + + 0.102731018 seconds time elapsed +``` + +Closes: https://lore.kernel.org/lkml/18f20d38-070c-4e17-bc90-cf7102e1e53d@linux.intel.com/ +Fixes: 035c17893082 ("perf parse-events: Add 'X' modifier to exclude an event from being regrouped") +Signed-off-by: Ian Rogers +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/parse-events.c | 16 ++++++++++------ + 1 file changed, 10 insertions(+), 6 deletions(-) + +diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c +index 90a765016f64f..cd9315d3ca117 100644 +--- a/tools/perf/util/parse-events.c ++++ b/tools/perf/util/parse-events.c +@@ -2121,14 +2121,18 @@ static int evlist__cmp(void *_fg_idx, const struct list_head *l, const struct li + * event's index is used. An index may be forced for events that + * must be in the same group, namely Intel topdown events. + */ +- if (*force_grouped_idx != -1 && arch_evsel__must_be_in_group(lhs)) { ++ if (lhs->dont_regroup) { ++ lhs_sort_idx = lhs_core->idx; ++ } else if (*force_grouped_idx != -1 && arch_evsel__must_be_in_group(lhs)) { + lhs_sort_idx = *force_grouped_idx; + } else { + bool lhs_has_group = lhs_core->leader != lhs_core || lhs_core->nr_members > 1; + + lhs_sort_idx = lhs_has_group ? lhs_core->leader->idx : lhs_core->idx; + } +- if (*force_grouped_idx != -1 && arch_evsel__must_be_in_group(rhs)) { ++ if (rhs->dont_regroup) { ++ rhs_sort_idx = rhs_core->idx; ++ } else if (*force_grouped_idx != -1 && arch_evsel__must_be_in_group(rhs)) { + rhs_sort_idx = *force_grouped_idx; + } else { + bool rhs_has_group = rhs_core->leader != rhs_core || rhs_core->nr_members > 1; +@@ -2226,10 +2230,10 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list) + */ + idx = 0; + list_for_each_entry(pos, list, core.node) { +- const struct evsel *pos_leader = evsel__leader(pos); ++ struct evsel *pos_leader = evsel__leader(pos); + const char *pos_pmu_name = pos->group_pmu_name; + const char *cur_leader_pmu_name; +- bool pos_force_grouped = force_grouped_idx != -1 && ++ bool pos_force_grouped = force_grouped_idx != -1 && !pos->dont_regroup && + arch_evsel__must_be_in_group(pos); + + /* Reset index and nr_members. */ +@@ -2243,8 +2247,8 @@ static int parse_events__sort_events_and_fix_groups(struct list_head *list) + * groups can't span PMUs. + */ + if (!cur_leader || pos->dont_regroup) { +- cur_leader = pos; +- cur_leaders_grp = &pos->core; ++ cur_leader = pos->dont_regroup ? pos_leader : pos; ++ cur_leaders_grp = &cur_leader->core; + if (pos_force_grouped) + force_grouped_leader = pos; + } +-- +2.51.0 + diff --git a/queue-6.18/perf-record-skip-synthesize-event-when-open-evsel-fa.patch b/queue-6.18/perf-record-skip-synthesize-event-when-open-evsel-fa.patch new file mode 100644 index 0000000000..973b208593 --- /dev/null +++ b/queue-6.18/perf-record-skip-synthesize-event-when-open-evsel-fa.patch @@ -0,0 +1,71 @@ +From c17b2cd38c8096968197526d88b8f85f9aad2770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:50:43 +0800 +Subject: perf record: skip synthesize event when open evsel failed + +From: Shuai Xue + +[ Upstream commit 163e5f2b96632b7fb2eaa965562aca0dbdf9f996 ] + +When using perf record with the `--overwrite` option, a segmentation fault +occurs if an event fails to open. For example: + + perf record -e cycles-ct -F 1000 -a --overwrite + Error: + cycles-ct:H: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + perf: Segmentation fault + #0 0x6466b6 in dump_stack debug.c:366 + #1 0x646729 in sighandler_dump_stack debug.c:378 + #2 0x453fd1 in sigsegv_handler builtin-record.c:722 + #3 0x7f8454e65090 in __restore_rt libc-2.32.so[54090] + #4 0x6c5671 in __perf_event__synthesize_id_index synthetic-events.c:1862 + #5 0x6c5ac0 in perf_event__synthesize_id_index synthetic-events.c:1943 + #6 0x458090 in record__synthesize builtin-record.c:2075 + #7 0x45a85a in __cmd_record builtin-record.c:2888 + #8 0x45deb6 in cmd_record builtin-record.c:4374 + #9 0x4e5e33 in run_builtin perf.c:349 + #10 0x4e60bf in handle_internal_command perf.c:401 + #11 0x4e6215 in run_argv perf.c:448 + #12 0x4e653a in main perf.c:555 + #13 0x7f8454e4fa72 in __libc_start_main libc-2.32.so[3ea72] + #14 0x43a3ee in _start ??:0 + +The --overwrite option implies --tail-synthesize, which collects non-sample +events reflecting the system status when recording finishes. However, when +evsel opening fails (e.g., unsupported event 'cycles-ct'), session->evlist +is not initialized and remains NULL. The code unconditionally calls +record__synthesize() in the error path, which iterates through the NULL +evlist pointer and causes a segfault. + +To fix it, move the record__synthesize() call inside the error check block, so +it's only called when there was no error during recording, ensuring that evlist +is properly initialized. + +Fixes: 4ea648aec019 ("perf record: Add --tail-synthesize option") +Signed-off-by: Shuai Xue +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c +index d76f01956e33b..b1fb87016d5aa 100644 +--- a/tools/perf/builtin-record.c ++++ b/tools/perf/builtin-record.c +@@ -2883,11 +2883,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) + rec->bytes_written += off_cpu_write(rec->session); + + record__read_lost_samples(rec); +- record__synthesize(rec, true); + /* this will be recalculated during process_buildids() */ + rec->samples = 0; + + if (!err) { ++ record__synthesize(rec, true); + if (!rec->timestamp_filename) { + record__finish_output(rec); + } else { +-- +2.51.0 + diff --git a/queue-6.18/perf-stat-allow-no-events-to-open-if-this-is-a-null-.patch b/queue-6.18/perf-stat-allow-no-events-to-open-if-this-is-a-null-.patch new file mode 100644 index 0000000000..9b4484f7fd --- /dev/null +++ b/queue-6.18/perf-stat-allow-no-events-to-open-if-this-is-a-null-.patch @@ -0,0 +1,37 @@ +From 0d29c47fe8cd772bc0d4c9e1d8624bee8f8af20d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 13:47:00 -0800 +Subject: perf stat: Allow no events to open if this is a "--null" run + +From: Ian Rogers + +[ Upstream commit 6744c0b182c1f371135bc3f4e62b96ad884c9f89 ] + +It is intended that a "--null" run doesn't open any events. + +Fixes: 2cc7aa995ce9 ("perf stat: Refactor retry/skip/fatal error handling") +Tested-by: Ingo Molnar +Signed-off-by: Ian Rogers +Tested-by: Thomas Richter +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-stat.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c +index f1c9d6c94fc50..b6533dcf5465b 100644 +--- a/tools/perf/builtin-stat.c ++++ b/tools/perf/builtin-stat.c +@@ -856,7 +856,7 @@ static int __run_perf_stat(int argc, const char **argv, int run_idx) + goto err_out; + } + } +- if (!has_supported_counters) { ++ if (!has_supported_counters && !stat_config.null_run) { + evsel__open_strerror(evlist__first(evsel_list), &target, open_err, + msg, sizeof(msg)); + ui__error("No supported events found.\n%s\n", msg); +-- +2.51.0 + diff --git a/queue-6.18/perf-tools-fix-missing-feature-check-for-inherit-sam.patch b/queue-6.18/perf-tools-fix-missing-feature-check-for-inherit-sam.patch new file mode 100644 index 0000000000..57dc78d401 --- /dev/null +++ b/queue-6.18/perf-tools-fix-missing-feature-check-for-inherit-sam.patch @@ -0,0 +1,47 @@ +From 3f360545fcb5d53f4817224c57b849dcf1beaff0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:59:44 -0800 +Subject: perf tools: Fix missing feature check for inherit + SAMPLE_READ + +From: Namhyung Kim + +[ Upstream commit 367377f45c0b568882567f797b7b18b263505be7 ] + +It should also have PERF_SAMPLE_TID to enable inherit and PERF_SAMPLE_READ +on recent kernels. Not having _TID makes the feature check wrongly detect +the inherit and _READ support. + +It was reported that the following command failed due to the error in +the missing feature check on Intel SPR machines. + + $ perf record -e '{cpu/mem-loads-aux/S,cpu/mem-loads,ldlat=3/PS}' -- ls + Error: + Failure to open event 'cpu/mem-loads,ldlat=3/PS' on PMU 'cpu' which will be removed. + Invalid event (cpu/mem-loads,ldlat=3/PS) in per-thread mode, enable system wide with '-a'. + +Reviewed-by: Ian Rogers +Fixes: 3b193a57baf15c468 ("perf tools: Detect missing kernel features properly") +Reported-and-tested-by: Chen, Zide +Closes: https://lore.kernel.org/lkml/20251022220802.1335131-1-zide.chen@intel.com/ +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/evsel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c +index 56ebefd075f2e..9df9818e37013 100644 +--- a/tools/perf/util/evsel.c ++++ b/tools/perf/util/evsel.c +@@ -2473,7 +2473,7 @@ static bool evsel__detect_missing_features(struct evsel *evsel, struct perf_cpu + /* Please add new feature detection here. */ + + attr.inherit = true; +- attr.sample_type = PERF_SAMPLE_READ; ++ attr.sample_type = PERF_SAMPLE_READ | PERF_SAMPLE_TID; + if (has_attr_feature(&attr, /*flags=*/0)) + goto found; + perf_missing_features.inherit_sample_read = true; +-- +2.51.0 + diff --git a/queue-6.18/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-6.18/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..df8cff8ed9 --- /dev/null +++ b/queue-6.18/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From e09e1ac0a51d7cb33b3af84601eefe33d1e621b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index aed65b1abe669..f6c268c588a56 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -964,11 +964,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso__kernel(dso) == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + map__zput(curr_map); +-- +2.51.0 + diff --git a/queue-6.18/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch b/queue-6.18/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch new file mode 100644 index 0000000000..ee2b8cde40 --- /dev/null +++ b/queue-6.18/perf-tools-mark-split-kallsyms-dsos-as-loaded.patch @@ -0,0 +1,41 @@ +From 1e35f5f9c878352179e644c6816f9f27f9c058f2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:14 -0800 +Subject: perf tools: Mark split kallsyms DSOs as loaded + +From: Namhyung Kim + +[ Upstream commit 7da4d60db33cccd8f4c445ab20bba71531435ee5 ] + +The maps__split_kallsyms() will split symbols to module DSOs if it comes +from a module. It also handled some unusual kernel symbols after modules +by creating new kernel maps like "[kernel].0". + +But they are pseudo DSOs to have those unexpected symbols. They should +not be considered as unloaded kernel DSOs. Otherwise the dso__load() +for them will end up calling dso__load_kallsyms() and then +maps__split_kallsyms() again and again. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index 948d3e8ad782b..aed65b1abe669 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -976,6 +976,7 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + return -1; + + dso__set_kernel(ndso, dso__kernel(dso)); ++ dso__set_loaded(ndso); + + curr_map = map__new2(pos->start, ndso); + if (curr_map == NULL) { +-- +2.51.0 + diff --git a/queue-6.18/perf-vendor-metrics-s390-avoid-has_event-instruction.patch b/queue-6.18/perf-vendor-metrics-s390-avoid-has_event-instruction.patch new file mode 100644 index 0000000000..aaef139c95 --- /dev/null +++ b/queue-6.18/perf-vendor-metrics-s390-avoid-has_event-instruction.patch @@ -0,0 +1,97 @@ +From 0d2b5b04a34842190bcb58ecc4f88da859520473 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 08:24:39 -0800 +Subject: perf vendor metrics s390: Avoid has_event(INSTRUCTIONS) + +From: Ian Rogers + +[ Upstream commit c1932fb85af8e51ac9f6bd9947145b06c716106e ] + +The instructions event is now provided in json meaning the has_event +test always succeeds. Switch to using non-legacy event names in the +affected metrics. + +Reported-by: Thomas Richter +Closes: https://lore.kernel.org/linux-perf-users/3e80f453-f015-4f4f-93d3-8df6bb6b3c95@linux.ibm.com/ +Fixes: 0012e0fa221b ("perf jevents: Add legacy-hardware and legacy-cache json") +Signed-off-by: Ian Rogers +Reviewed-by: Thomas Richter +Tested-by: Thomas Richter +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/pmu-events/arch/s390/cf_z16/transaction.json | 8 ++++---- + tools/perf/pmu-events/arch/s390/cf_z17/transaction.json | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json +index 3ab1d3a6638c4..57b785307a85f 100644 +--- a/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json ++++ b/tools/perf/pmu-events/arch/s390/cf_z16/transaction.json +@@ -7,17 +7,17 @@ + { + "BriefDescription": "Cycles per Instruction", + "MetricName": "cpi", +- "MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(CPU_CYCLES) else 0" + }, + { + "BriefDescription": "Problem State Instruction Ratio", + "MetricName": "prbstate", +- "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(PROBLEM_STATE_INSTRUCTIONS) else 0" + }, + { + "BriefDescription": "Level One Miss per 100 Instructions", + "MetricName": "l1mp", +- "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(L1I_DIR_WRITES) else 0" + }, + { + "BriefDescription": "Percentage sourced from Level 2 cache", +@@ -52,7 +52,7 @@ + { + "BriefDescription": "Estimated Instruction Complexity CPI infinite Level 1", + "MetricName": "est_cpi", +- "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(CPU_CYCLES) else 0" + }, + { + "BriefDescription": "Estimated Sourcing Cycles per Level 1 Miss", +diff --git a/tools/perf/pmu-events/arch/s390/cf_z17/transaction.json b/tools/perf/pmu-events/arch/s390/cf_z17/transaction.json +index 74df533c8b6fa..7ded6a5a76c0f 100644 +--- a/tools/perf/pmu-events/arch/s390/cf_z17/transaction.json ++++ b/tools/perf/pmu-events/arch/s390/cf_z17/transaction.json +@@ -7,17 +7,17 @@ + { + "BriefDescription": "Cycles per Instruction", + "MetricName": "cpi", +- "MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "CPU_CYCLES / INSTRUCTIONS if has_event(CPU_CYCLES) else 0" + }, + { + "BriefDescription": "Problem State Instruction Ratio", + "MetricName": "prbstate", +- "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "(PROBLEM_STATE_INSTRUCTIONS / INSTRUCTIONS) * 100 if has_event(PROBLEM_STATE_INSTRUCTIONS) else 0" + }, + { + "BriefDescription": "Level One Miss per 100 Instructions", + "MetricName": "l1mp", +- "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "((L1I_DIR_WRITES + L1D_DIR_WRITES) / INSTRUCTIONS) * 100 if has_event(L1I_DIR_WRITES) else 0" + }, + { + "BriefDescription": "Percentage sourced from Level 2 cache", +@@ -52,7 +52,7 @@ + { + "BriefDescription": "Estimated Instruction Complexity CPI infinite Level 1", + "MetricName": "est_cpi", +- "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(INSTRUCTIONS) else 0" ++ "MetricExpr": "(CPU_CYCLES / INSTRUCTIONS) - (L1C_TLB2_MISSES / INSTRUCTIONS) if has_event(L1C_TLB2_MISSES) else 0" + }, + { + "BriefDescription": "Estimated Sourcing Cycles per Level 1 Miss", +-- +2.51.0 + diff --git a/queue-6.18/perf-x86-fix-null-event-access-and-potential-pebs-re.patch b/queue-6.18/perf-x86-fix-null-event-access-and-potential-pebs-re.patch new file mode 100644 index 0000000000..0d77bfb213 --- /dev/null +++ b/queue-6.18/perf-x86-fix-null-event-access-and-potential-pebs-re.patch @@ -0,0 +1,97 @@ +From e5ef95f61b34d3aed28193d33602cded2e90b1da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:26 +0800 +Subject: perf/x86: Fix NULL event access and potential PEBS record loss + +From: Dapeng Mi + +[ Upstream commit 7e772a93eb61cb6265bdd1c5bde17d0f2718b452 ] + +When intel_pmu_drain_pebs_icl() is called to drain PEBS records, the +perf_event_overflow() could be called to process the last PEBS record. + +While perf_event_overflow() could trigger the interrupt throttle and +stop all events of the group, like what the below call-chain shows. + +perf_event_overflow() + -> __perf_event_overflow() + ->__perf_event_account_interrupt() + -> perf_event_throttle_group() + -> perf_event_throttle() + -> event->pmu->stop() + -> x86_pmu_stop() + +The side effect of stopping the events is that all corresponding event +pointers in cpuc->events[] array are cleared to NULL. + +Assume there are two PEBS events (event a and event b) in a group. When +intel_pmu_drain_pebs_icl() calls perf_event_overflow() to process the +last PEBS record of PEBS event a, interrupt throttle is triggered and +all pointers of event a and event b are cleared to NULL. Then +intel_pmu_drain_pebs_icl() tries to process the last PEBS record of +event b and encounters NULL pointer access. + +To avoid this issue, move cpuc->events[] clearing from x86_pmu_stop() +to x86_pmu_del(). It's safe since cpuc->active_mask or +cpuc->pebs_enabled is always checked before access the event pointer +from cpuc->events[]. + +Closes: https://lore.kernel.org/oe-lkp/202507042103.a15d2923-lkp@intel.com +Fixes: 9734e25fbf5a ("perf: Fix the throttle logic for a group") +Reported-by: kernel test robot +Suggested-by: Peter Zijlstra +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-3-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c +index fa6c47b509897..dd9ff120ad437 100644 +--- a/arch/x86/events/core.c ++++ b/arch/x86/events/core.c +@@ -1344,6 +1344,7 @@ static void x86_pmu_enable(struct pmu *pmu) + hwc->state |= PERF_HES_ARCH; + + x86_pmu_stop(event, PERF_EF_UPDATE); ++ cpuc->events[hwc->idx] = NULL; + } + + /* +@@ -1365,6 +1366,7 @@ static void x86_pmu_enable(struct pmu *pmu) + * if cpuc->enabled = 0, then no wrmsr as + * per x86_pmu_enable_event() + */ ++ cpuc->events[hwc->idx] = event; + x86_pmu_start(event, PERF_EF_RELOAD); + } + cpuc->n_added = 0; +@@ -1531,7 +1533,6 @@ static void x86_pmu_start(struct perf_event *event, int flags) + + event->hw.state = 0; + +- cpuc->events[idx] = event; + __set_bit(idx, cpuc->active_mask); + static_call(x86_pmu_enable)(event); + perf_event_update_userpage(event); +@@ -1610,7 +1611,6 @@ void x86_pmu_stop(struct perf_event *event, int flags) + if (test_bit(hwc->idx, cpuc->active_mask)) { + static_call(x86_pmu_disable)(event); + __clear_bit(hwc->idx, cpuc->active_mask); +- cpuc->events[hwc->idx] = NULL; + WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); + hwc->state |= PERF_HES_STOPPED; + } +@@ -1648,6 +1648,7 @@ static void x86_pmu_del(struct perf_event *event, int flags) + * Not a TXN, therefore cleanup properly. + */ + x86_pmu_stop(event, PERF_EF_UPDATE); ++ cpuc->events[event->hw.idx] = NULL; + + for (i = 0; i < cpuc->n_events; i++) { + if (event == cpuc->event_list[i]) +-- +2.51.0 + diff --git a/queue-6.18/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-6.18/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..f14cbf7d5d --- /dev/null +++ b/queue-6.18/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From 1da69a1874e7156653d063a0853aadad41639999 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index fe65be0b9d9c4..9b824ed6fc1de 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -4029,7 +4029,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-6.18/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch b/queue-6.18/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch new file mode 100644 index 0000000000..d0ff4d83ae --- /dev/null +++ b/queue-6.18/perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch @@ -0,0 +1,47 @@ +From 3132ac425b6ee0e16fac50597c9298302d984a44 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 15:37:52 -0700 +Subject: perf/x86/intel/cstate: Remove PC3 support from LunarLake + +From: Zhang Rui + +[ Upstream commit 4ba45f041abe60337fdeeb68553b9ee1217d544e ] + +LunarLake doesn't support Package C3. Remove the PC3 residency counter +support from LunarLake. + +Fixes: 26579860fbd5 ("perf/x86/intel/cstate: Add Lunarlake support") +Signed-off-by: Zhang Rui +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Kan Liang +Reviewed-by: Dapeng Mi +Link: https://patch.msgid.link/20251023223754.1743928-3-zide.chen@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/cstate.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c +index ec753e39b0077..6f5286a99e0c3 100644 +--- a/arch/x86/events/intel/cstate.c ++++ b/arch/x86/events/intel/cstate.c +@@ -70,7 +70,7 @@ + * perf code: 0x01 + * Available model: NHM,WSM,SNB,IVB,HSW,BDW,SKL,KNL, + * GLM,CNL,KBL,CML,ICL,TGL,TNT,RKL, +- * ADL,RPL,MTL,ARL,LNL ++ * ADL,RPL,MTL,ARL + * Scope: Package (physical package) + * MSR_PKG_C6_RESIDENCY: Package C6 Residency Counter. + * perf code: 0x02 +@@ -522,7 +522,6 @@ static const struct cstate_model lnl_cstates __initconst = { + BIT(PERF_CSTATE_CORE_C7_RES), + + .pkg_events = BIT(PERF_CSTATE_PKG_C2_RES) | +- BIT(PERF_CSTATE_PKG_C3_RES) | + BIT(PERF_CSTATE_PKG_C6_RES) | + BIT(PERF_CSTATE_PKG_C10_RES), + }; +-- +2.51.0 + diff --git a/queue-6.18/phy-freescale-initialize-priv-lock.patch b/queue-6.18/phy-freescale-initialize-priv-lock.patch new file mode 100644 index 0000000000..b2e1db8012 --- /dev/null +++ b/queue-6.18/phy-freescale-initialize-priv-lock.patch @@ -0,0 +1,71 @@ +From e0a31bc5d7298e5aeebe46e54d940429d4fcb56a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 25 Sep 2025 09:38:06 +0800 +Subject: phy: freescale: Initialize priv->lock + +From: Xiaolei Wang + +[ Upstream commit 95e5905698983df94069e185f9eb3c67c7cf75d5 ] + +Initialize priv->lock to fix the following warning. + +WARNING: CPU: 0 PID: 12 at kernel/locking/mutex.c:577 __mutex_lock+0x70c/0x8b8 + Modules linked in: + Hardware name: Freescale i.MX8QM MEK (DT) + Call trace: + __mutex_lock+0x70c/0x8b8 (P) + mutex_lock_nested+0x24/0x30 + imx_hsio_power_on+0x4c/0x764 + phy_power_on+0x7c/0x12c + imx_pcie_host_init+0x1d0/0x4d4 + dw_pcie_host_init+0x188/0x4b0 + imx_pcie_probe+0x324/0x6f4 + platform_probe+0x5c/0x98 + really_probe+0xbc/0x29c + __driver_probe_device+0x78/0x12c + driver_probe_device+0xd8/0x160 + __device_attach_driver+0xb8/0x138 + bus_for_each_drv+0x84/0xe4 + __device_attach_async_helper+0xb8/0xdc + async_run_entry_fn+0x34/0xe0 + process_one_work+0x220/0x694 + worker_thread+0x1c0/0x36c + kthread+0x14c/0x224 + +Fixes: 82c56b6dd24f ("phy: freescale: imx8qm-hsio: Add i.MX8QM HSIO PHY driver support") +Signed-off-by: Xiaolei Wang +Reviewed-by: Frank Li +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20250925013806.569658-1-xiaolei.wang@windriver.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/freescale/phy-fsl-imx8qm-hsio.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +index 5dca93cd325c8..977d21d753a59 100644 +--- a/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c ++++ b/drivers/phy/freescale/phy-fsl-imx8qm-hsio.c +@@ -533,7 +533,7 @@ static struct phy *imx_hsio_xlate(struct device *dev, + + static int imx_hsio_probe(struct platform_device *pdev) + { +- int i; ++ int i, ret; + void __iomem *off; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; +@@ -545,6 +545,9 @@ static int imx_hsio_probe(struct platform_device *pdev) + return -ENOMEM; + priv->dev = &pdev->dev; + priv->drvdata = of_device_get_match_data(dev); ++ ret = devm_mutex_init(dev, &priv->lock); ++ if (ret) ++ return ret; + + /* Get HSIO configuration mode */ + if (of_property_read_string(np, "fsl,hsio-cfg", &priv->hsio_cfg)) +-- +2.51.0 + diff --git a/queue-6.18/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-6.18/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..d2f01988af --- /dev/null +++ b/queue-6.18/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From 0bd586d0bdfa363abd391340dfafaf6f05d8f7a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index ef0ef1570d392..48d43f60b8ff8 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2625,7 +2625,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2648,12 +2648,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-6.18/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch b/queue-6.18/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch new file mode 100644 index 0000000000..6757c3e6a2 --- /dev/null +++ b/queue-6.18/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch @@ -0,0 +1,94 @@ +From 86a59c7b8e706efd75bfadc2c125bd4a79a4ade1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 16:58:05 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Fix an error handling path in + rcar_gen3_phy_usb2_probe() + +From: Christophe JAILLET + +[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ] + +If an error occurs after the reset_control_deassert(), +reset_control_assert() must be called, as already done in the remove +function. + +Use devm_add_action_or_reset() to add the missing call and simplify the +.remove() function accordingly. + +While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. + +[claudiu.beznea: removed "struct reset_control *rstc = data;" from + rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] + +Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") +Signed-off-by: Christophe JAILLET +Reviewed-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Tested-by: Wolfram Sang +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index 3f6b480e10922..a38ead7c8055d 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -134,7 +134,6 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; +- struct reset_control *rstc; + struct work_struct work; + spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; +@@ -771,21 +770,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static void rcar_gen3_reset_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) + { + struct device *dev = channel->dev; ++ struct reset_control *rstc; + int ret; + u32 val; + +- channel->rstc = devm_reset_control_array_get_shared(dev); +- if (IS_ERR(channel->rstc)) +- return PTR_ERR(channel->rstc); ++ rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(rstc)) ++ return PTR_ERR(rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + +- ret = reset_control_deassert(channel->rstc); ++ ret = reset_control_deassert(rstc); ++ if (ret) ++ goto rpm_put; ++ ++ ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); + if (ret) + goto rpm_put; + +@@ -924,7 +933,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + +- reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + }; + +-- +2.51.0 + diff --git a/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch b/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch new file mode 100644 index 0000000000..000f4430a1 --- /dev/null +++ b/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch @@ -0,0 +1,52 @@ +From 88cb93cac75ea4f8435ff2fe58960954c9482117 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 17:52:05 +0800 +Subject: phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3528 + +From: Shawn Lin + +[ Upstream commit a2a18e5da64f8da306fa97c397b4c739ea776f37 ] + +When PCIe link enters L1 PM substates, the PHY will turn off its +PLL for power-saving. However, it turns off the PLL too fast which +leads the PHY to be broken. According to the PHY document, we need +to delay PLL turnoff time. + +Fixes: bbcca4fac873 ("phy: rockchip: naneng-combphy: Add RK3528 support") +Signed-off-by: Shawn Lin +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/1763459526-35004-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index a3ef19807b9ef..e303bec8a996f 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -21,6 +21,9 @@ + #define REF_CLOCK_100MHz (100 * HZ_PER_MHZ) + + /* RK3528 COMBO PHY REG */ ++#define RK3528_PHYREG5 0x14 ++#define RK3528_PHYREG5_GATE_TX_PCK_SEL BIT(3) ++#define RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF BIT(3) + #define RK3528_PHYREG6 0x18 + #define RK3528_PHYREG6_PLL_KVCO GENMASK(12, 10) + #define RK3528_PHYREG6_PLL_KVCO_VALUE 0x2 +@@ -504,6 +507,10 @@ static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { ++ /* Gate_tx_pck_sel length select for L1ss support */ ++ rockchip_combphy_updatel(priv, RK3528_PHYREG5_GATE_TX_PCK_SEL, ++ RK3528_PHYREG5_GATE_TX_PCK_DLY_PLL_OFF, RK3528_PHYREG5); ++ + /* PLL KVCO tuning fine */ + val = FIELD_PREP(RK3528_PHYREG6_PLL_KVCO, RK3528_PHYREG6_PLL_KVCO_VALUE); + rockchip_combphy_updatel(priv, RK3528_PHYREG6_PLL_KVCO, val, +-- +2.51.0 + diff --git a/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch-10421 b/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch-10421 new file mode 100644 index 0000000000..462dae2a5f --- /dev/null +++ b/queue-6.18/phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch-10421 @@ -0,0 +1,53 @@ +From 4a08d78f26b80f63a06b7a798877cfdb34f43d68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 17:52:06 +0800 +Subject: phy: rockchip: naneng-combphy: Fix PCIe L1ss support RK3562 + +From: Shawn Lin + +[ Upstream commit be866e68966d20bcc4a73708093d577176f99c0c ] + +When PCIe link enters L1 PM substates, the PHY will turn off its +PLL for power-saving. However, it turns off the PLL too fast which +leads the PHY to be broken. According to the PHY document, we need +to delay PLL turnoff time. + +Fixes: f13bff25161b ("phy: rockchip-naneng-combo: Support rk3562") +Signed-off-by: Shawn Lin +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/1763459526-35004-2-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-naneng-combphy.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +index e303bec8a996f..7f8fc8e6d4890 100644 +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -106,6 +106,10 @@ + #define RK3568_PHYREG18 0x44 + #define RK3568_PHYREG18_PLL_LOOP 0x32 + ++#define RK3568_PHYREG30 0x74 ++#define RK3568_PHYREG30_GATE_TX_PCK_SEL BIT(7) ++#define RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF BIT(7) ++ + #define RK3568_PHYREG32 0x7C + #define RK3568_PHYREG32_SSC_MASK GENMASK(7, 4) + #define RK3568_PHYREG32_SSC_DIR_MASK GENMASK(5, 4) +@@ -664,6 +668,10 @@ static int rk3562_combphy_cfg(struct rockchip_combphy_priv *priv) + case REF_CLOCK_100MHz: + rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); + if (priv->type == PHY_TYPE_PCIE) { ++ /* Gate_tx_pck_sel length select for L1ss support */ ++ rockchip_combphy_updatel(priv, RK3568_PHYREG30_GATE_TX_PCK_SEL, ++ RK3568_PHYREG30_GATE_TX_PCK_DLY_PLL_OFF, ++ RK3568_PHYREG30); + /* PLL KVCO tuning fine */ + val = FIELD_PREP(RK3568_PHYREG33_PLL_KVCO_MASK, + RK3568_PHYREG33_PLL_KVCO_VALUE); +-- +2.51.0 + diff --git a/queue-6.18/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch b/queue-6.18/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch new file mode 100644 index 0000000000..1183d9a425 --- /dev/null +++ b/queue-6.18/phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch @@ -0,0 +1,78 @@ +From 91fd0a3b7b3c5eb6fd78d1a48fa02a5a41a39323 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:54 +0200 +Subject: phy: rockchip: samsung-hdptx: Fix reported clock rate in high bpc + mode + +From: Cristian Ciocaltea + +[ Upstream commit 72126e9623e1696ea83c77ef6d0306a6263bdd6b ] + +When making use of the clock provider functionality, the output clock +does normally match the TMDS character rate, which is what the PHY PLL +gets configured to. + +However, this is only applicable for default color depth of 8 bpc. For +higher depths, the output clock is further divided by the hardware +according to the formula: + + output_clock_rate = tmds_char_rate * 8 / bpc + +Since the existence of the clock divider wasn't taken into account when +support for high bpc has been introduced, make the necessary adjustments +to report the correct clock rate. + +Fixes: 9d0ec51d7c22 ("phy: rockchip: samsung-hdptx: Add high color depth management") +Reported-by: Andy Yan +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-1-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 14 ++++++++------ + 1 file changed, 8 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 01bbf668e05ef..aee03e8655f66 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -1037,7 +1037,8 @@ static int rk_hdptx_ropll_tmds_cmn_config(struct rk_hdptx_phy *hdptx) + + ret = rk_hdptx_post_enable_pll(hdptx); + if (!ret) +- hdptx->hw_rate = hdptx->hdmi_cfg.tmds_char_rate; ++ hdptx->hw_rate = DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, ++ hdptx->hdmi_cfg.bpc); + + return ret; + } +@@ -1895,19 +1896,20 @@ static long rk_hdptx_phy_clk_round_rate(struct clk_hw *hw, unsigned long rate, + * hence ensure rk_hdptx_phy_clk_set_rate() won't be invoked with + * a different rate argument. + */ +- return hdptx->hdmi_cfg.tmds_char_rate; ++ return DIV_ROUND_CLOSEST_ULL(hdptx->hdmi_cfg.tmds_char_rate * 8, hdptx->hdmi_cfg.bpc); + } + + static int rk_hdptx_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) + { + struct rk_hdptx_phy *hdptx = to_rk_hdptx_phy(hw); ++ unsigned long long tmds_rate = DIV_ROUND_CLOSEST_ULL(rate * hdptx->hdmi_cfg.bpc, 8); + + /* Revert any unlikely TMDS char rate change since round_rate() */ +- if (hdptx->hdmi_cfg.tmds_char_rate != rate) { +- dev_warn(hdptx->dev, "Reverting unexpected rate change from %lu to %llu\n", +- rate, hdptx->hdmi_cfg.tmds_char_rate); +- hdptx->hdmi_cfg.tmds_char_rate = rate; ++ if (hdptx->hdmi_cfg.tmds_char_rate != tmds_rate) { ++ dev_warn(hdptx->dev, "Reverting unexpected rate change from %llu to %llu\n", ++ tmds_rate, hdptx->hdmi_cfg.tmds_char_rate); ++ hdptx->hdmi_cfg.tmds_char_rate = tmds_rate; + } + + /* +-- +2.51.0 + diff --git a/queue-6.18/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch b/queue-6.18/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch new file mode 100644 index 0000000000..012aaf4dbe --- /dev/null +++ b/queue-6.18/phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch @@ -0,0 +1,59 @@ +From 7f2f2e0db13bb3c93b431231d619040d4e47bd80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:56 +0200 +Subject: phy: rockchip: samsung-hdptx: Prevent Inter-Pair Skew from exceeding + the limits + +From: Cristian Ciocaltea + +[ Upstream commit 51023cf6cc5db3423dea6620746d9087e336e024 ] + +Fixup PHY deskew FIFO to prevent the phase of D2 lane going ahead of +other lanes. It's worth noting this might only happen when dealing with +HDMI 2.0 rates. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-3-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index 8ba9b53c2309b..29de2f7bdae8a 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -668,13 +668,9 @@ static const struct reg_sequence rk_hdtpx_common_lane_init_seq[] = { + + static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0312), 0x00), +- REG_SEQ0(LANE_REG(031e), 0x00), + REG_SEQ0(LANE_REG(0412), 0x00), +- REG_SEQ0(LANE_REG(041e), 0x00), + REG_SEQ0(LANE_REG(0512), 0x00), +- REG_SEQ0(LANE_REG(051e), 0x00), + REG_SEQ0(LANE_REG(0612), 0x00), +- REG_SEQ0(LANE_REG(061e), 0x08), + REG_SEQ0(LANE_REG(0303), 0x2f), + REG_SEQ0(LANE_REG(0403), 0x2f), + REG_SEQ0(LANE_REG(0503), 0x2f), +@@ -687,6 +683,11 @@ static const struct reg_sequence rk_hdtpx_tmds_lane_init_seq[] = { + REG_SEQ0(LANE_REG(0406), 0x1c), + REG_SEQ0(LANE_REG(0506), 0x1c), + REG_SEQ0(LANE_REG(0606), 0x1c), ++ /* Keep Inter-Pair Skew in the limits */ ++ REG_SEQ0(LANE_REG(031e), 0x02), ++ REG_SEQ0(LANE_REG(041e), 0x02), ++ REG_SEQ0(LANE_REG(051e), 0x02), ++ REG_SEQ0(LANE_REG(061e), 0x0a), + }; + + static struct tx_drv_ctrl tx_drv_ctrl_rbr[4][4] = { +-- +2.51.0 + diff --git a/queue-6.18/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch b/queue-6.18/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch new file mode 100644 index 0000000000..ed04d7fba4 --- /dev/null +++ b/queue-6.18/phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch @@ -0,0 +1,53 @@ +From 49e05f75daa7630b9253689c0bc1254a49586050 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 10:00:55 +0200 +Subject: phy: rockchip: samsung-hdptx: Reduce ROPLL loop bandwidth + +From: Cristian Ciocaltea + +[ Upstream commit 8daaced9f5eeb4a2c8ca08b0a8286b6a498a8387 ] + +Due to its relatively low frequency, a noise stemming from the 24MHz PLL +reference clock may traverse the low-pass loop filter of ROPLL, which +could potentially generate some HDMI flash artifacts. + +Reduce ROPLL loop bandwidth in an attempt to mitigate the problem. + +Fixes: 553be2830c5f ("phy: rockchip: Add Samsung HDMI/eDP Combo PHY driver") +Co-developed-by: Algea Cao +Signed-off-by: Algea Cao +Signed-off-by: Cristian Ciocaltea +Reviewed-by: Neil Armstrong +Link: https://patch.msgid.link/20251028-phy-hdptx-fixes-v1-2-ecc642a59d94@collabora.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +index aee03e8655f66..8ba9b53c2309b 100644 +--- a/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c ++++ b/drivers/phy/rockchip/phy-rockchip-samsung-hdptx.c +@@ -500,9 +500,7 @@ static const struct reg_sequence rk_hdtpx_common_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0043), 0x00), + REG_SEQ0(CMN_REG(0044), 0x46), + REG_SEQ0(CMN_REG(0045), 0x24), +- REG_SEQ0(CMN_REG(0046), 0xff), + REG_SEQ0(CMN_REG(0047), 0x00), +- REG_SEQ0(CMN_REG(0048), 0x44), + REG_SEQ0(CMN_REG(0049), 0xfa), + REG_SEQ0(CMN_REG(004a), 0x08), + REG_SEQ0(CMN_REG(004b), 0x00), +@@ -575,6 +573,8 @@ static const struct reg_sequence rk_hdtpx_tmds_cmn_init_seq[] = { + REG_SEQ0(CMN_REG(0034), 0x00), + REG_SEQ0(CMN_REG(003d), 0x40), + REG_SEQ0(CMN_REG(0042), 0x78), ++ REG_SEQ0(CMN_REG(0046), 0xdd), ++ REG_SEQ0(CMN_REG(0048), 0x11), + REG_SEQ0(CMN_REG(004e), 0x34), + REG_SEQ0(CMN_REG(005c), 0x25), + REG_SEQ0(CMN_REG(005e), 0x4f), +-- +2.51.0 + diff --git a/queue-6.18/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch b/queue-6.18/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch new file mode 100644 index 0000000000..143f4db77c --- /dev/null +++ b/queue-6.18/pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch @@ -0,0 +1,37 @@ +From 17754a8de14511d3f70beddf325febe7553ae5a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 09:45:49 +0100 +Subject: pidfs: add missing BUILD_BUG_ON() assert on struct pidfd_info + +From: Christian Brauner + +[ Upstream commit d8fc51d8fa3b9894713e7eebcf574bee488fa3e1 ] + +Validate that the size of struct pidfd_info is correctly updated. + +Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-4-ca449b7b7aa0@kernel.org +Fixes: 1d8db6fd698d ("pidfs, coredump: add PIDFD_INFO_COREDUMP") +Reviewed-by: Alexander Mikhalitsyn +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/pidfs.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/pidfs.c b/fs/pidfs.c +index 0ef5b47d796a2..f4d7dac1b4494 100644 +--- a/fs/pidfs.c ++++ b/fs/pidfs.c +@@ -306,6 +306,8 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) + const struct cred *c; + __u64 mask; + ++ BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER1); ++ + if (!uinfo) + return -EINVAL; + if (usize < PIDFD_INFO_SIZE_VER0) +-- +2.51.0 + diff --git a/queue-6.18/pidfs-add-missing-pidfd_info_size_ver1.patch b/queue-6.18/pidfs-add-missing-pidfd_info_size_ver1.patch new file mode 100644 index 0000000000..8da74bcd42 --- /dev/null +++ b/queue-6.18/pidfs-add-missing-pidfd_info_size_ver1.patch @@ -0,0 +1,36 @@ +From 703eebc9be88515530409192ced20ccef3601293 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 09:45:48 +0100 +Subject: pidfs: add missing PIDFD_INFO_SIZE_VER1 + +From: Christian Brauner + +[ Upstream commit 4061c43a99772c66c378cfacaa71550ab3b35909 ] + +We grew struct pidfd_info not too long ago. + +Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-3-ca449b7b7aa0@kernel.org +Fixes: 1d8db6fd698d ("pidfs, coredump: add PIDFD_INFO_COREDUMP") +Reviewed-by: Alexander Mikhalitsyn +Reviewed-by: Oleg Nesterov +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + include/uapi/linux/pidfd.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h +index 957db425d459a..6ccbabd9a68d8 100644 +--- a/include/uapi/linux/pidfd.h ++++ b/include/uapi/linux/pidfd.h +@@ -28,6 +28,7 @@ + #define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */ + + #define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */ ++#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */ + + /* + * Values for @coredump_mask in pidfd_info. +-- +2.51.0 + diff --git a/queue-6.18/pinctrl-qcom-glymur-drop-unnecessary-platform-data-f.patch b/queue-6.18/pinctrl-qcom-glymur-drop-unnecessary-platform-data-f.patch new file mode 100644 index 0000000000..f0e4c28258 --- /dev/null +++ b/queue-6.18/pinctrl-qcom-glymur-drop-unnecessary-platform-data-f.patch @@ -0,0 +1,39 @@ +From 074c8d4376c88371996c21c4fa56fb7ce1c7f969 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 15:17:11 +0300 +Subject: pinctrl: qcom: glymur: Drop unnecessary platform data from match + table + +From: Abel Vesa + +[ Upstream commit 37e7b536061a33c8f27030e3ffc5a717a6c319e3 ] + +The platform specific configuration is already passed on to the generic +msm probe. So it's useless to exist in the match table next to the +compatible. So drop it from match table. + +Fixes: 87ebcd8baebf ("pinctrl: qcom: Add glymur pinctrl driver") +Signed-off-by: Abel Vesa +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/qcom/pinctrl-glymur.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/qcom/pinctrl-glymur.c b/drivers/pinctrl/qcom/pinctrl-glymur.c +index 9913f98e95311..9781e7fcb3a11 100644 +--- a/drivers/pinctrl/qcom/pinctrl-glymur.c ++++ b/drivers/pinctrl/qcom/pinctrl-glymur.c +@@ -1743,7 +1743,7 @@ static const struct msm_pinctrl_soc_data glymur_tlmm = { + }; + + static const struct of_device_id glymur_tlmm_of_match[] = { +- { .compatible = "qcom,glymur-tlmm", .data = &glymur_tlmm }, ++ { .compatible = "qcom,glymur-tlmm", }, + { } + }; + +-- +2.51.0 + diff --git a/queue-6.18/pinctrl-qcom-glymur-fix-the-gpio-and-egpio-pin-funct.patch b/queue-6.18/pinctrl-qcom-glymur-fix-the-gpio-and-egpio-pin-funct.patch new file mode 100644 index 0000000000..41ff9381a7 --- /dev/null +++ b/queue-6.18/pinctrl-qcom-glymur-fix-the-gpio-and-egpio-pin-funct.patch @@ -0,0 +1,48 @@ +From 01edb0b005c0462a2c58754b3d75ee6813ed1906 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 15:17:12 +0300 +Subject: pinctrl: qcom: glymur: Fix the gpio and egpio pin functions + +From: Abel Vesa + +[ Upstream commit e73fda2dcb0bad6650e654556c5242b773707257 ] + +Mark the gpio/egpio as GPIO specific pin functions, othewise +the pin muxing generic framework will complain about the gpio +being already requested by a different owner. + +Fixes: 87ebcd8baebf ("pinctrl: qcom: Add glymur pinctrl driver") +Signed-off-by: Abel Vesa +Reviewed-by: Bartosz Golaszewski +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/qcom/pinctrl-glymur.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/qcom/pinctrl-glymur.c b/drivers/pinctrl/qcom/pinctrl-glymur.c +index 9781e7fcb3a11..335005084b6bc 100644 +--- a/drivers/pinctrl/qcom/pinctrl-glymur.c ++++ b/drivers/pinctrl/qcom/pinctrl-glymur.c +@@ -1316,7 +1316,7 @@ static const char *const wcn_sw_ctrl_groups[] = { + }; + + static const struct pinfunction glymur_functions[] = { +- MSM_PIN_FUNCTION(gpio), ++ MSM_GPIO_PIN_FUNCTION(gpio), + MSM_PIN_FUNCTION(resout_gpio_n), + MSM_PIN_FUNCTION(aoss_cti), + MSM_PIN_FUNCTION(asc_cci), +@@ -1342,7 +1342,7 @@ static const struct pinfunction glymur_functions[] = { + MSM_PIN_FUNCTION(edp0_hot), + MSM_PIN_FUNCTION(edp0_lcd), + MSM_PIN_FUNCTION(edp1_lcd), +- MSM_PIN_FUNCTION(egpio), ++ MSM_GPIO_PIN_FUNCTION(egpio), + MSM_PIN_FUNCTION(eusb_ac_en), + MSM_PIN_FUNCTION(gcc_gp1), + MSM_PIN_FUNCTION(gcc_gp2), +-- +2.51.0 + diff --git a/queue-6.18/pinctrl-renesas-rzg2l-fix-pmc-restore.patch b/queue-6.18/pinctrl-renesas-rzg2l-fix-pmc-restore.patch new file mode 100644 index 0000000000..420e4180ba --- /dev/null +++ b/queue-6.18/pinctrl-renesas-rzg2l-fix-pmc-restore.patch @@ -0,0 +1,41 @@ +From 8a739ea97949b7adae94b073ccd5a7c07af649b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 12:15:52 +0100 +Subject: pinctrl: renesas: rzg2l: Fix PMC restore + +From: Biju Das + +[ Upstream commit cea950101108b7bfffe26ec4007b8e263a4b56a8 ] + +PMC restore needs unlocking the register using the PWPR register. + +Fixes: ede014cd1ea6422d ("pinctrl: renesas: rzg2l: Add function pointer for PMC register write") +Signed-off-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250921111557.103069-2-biju.das.jz@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/renesas/pinctrl-rzg2l.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/renesas/pinctrl-rzg2l.c b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +index f524af6f586f4..94cb77949f595 100644 +--- a/drivers/pinctrl/renesas/pinctrl-rzg2l.c ++++ b/drivers/pinctrl/renesas/pinctrl-rzg2l.c +@@ -2993,7 +2993,11 @@ static void rzg2l_pinctrl_pm_setup_regs(struct rzg2l_pinctrl *pctrl, bool suspen + * Now cache the registers or set them in the order suggested by + * HW manual (section "Operation for GPIO Function"). + */ +- RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ if (suspend) ++ RZG2L_PCTRL_REG_ACCESS8(suspend, pctrl->base + PMC(off), cache->pmc[port]); ++ else ++ pctrl->data->pmc_writeb(pctrl, cache->pmc[port], PMC(off)); ++ + if (has_iolh) { + RZG2L_PCTRL_REG_ACCESS32(suspend, pctrl->base + IOLH(off), + cache->iolh[0][port]); +-- +2.51.0 + diff --git a/queue-6.18/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-6.18/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..31592eaa60 --- /dev/null +++ b/queue-6.18/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From effdf24e740f4f81bd1d0cc23d5af1e98af1057a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 6d580aa282ec9..998f23d6c3179 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -485,7 +485,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -549,9 +550,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-6.18/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.18/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..7af1f84bbf --- /dev/null +++ b/queue-6.18/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From ac3527cf2a9dc8426a5ae1bceab98a7401eef2c7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 3ebb468de830d..e73feb8ac90d1 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1671,7 +1671,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-6.18/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch b/queue-6.18/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch new file mode 100644 index 0000000000..72944cfd25 --- /dev/null +++ b/queue-6.18/pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch @@ -0,0 +1,43 @@ +From 193cd8d4bfd38b3a00cbed272000aa71169c0a0b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Sep 2025 14:21:35 +0800 +Subject: PM / devfreq: hisi: Fix potential UAF in OPP handling + +From: Pengjie Zhang + +[ Upstream commit 26dd44a40096468396b6438985d8e44e0743f64c ] + +Ensure all required data is acquired before calling dev_pm_opp_put(opp) +to maintain correct resource acquisition and release order. + +Fixes: 7da2fdaaa1e6 ("PM / devfreq: Add HiSilicon uncore frequency scaling driver") +Signed-off-by: Pengjie Zhang +Reviewed-by: Jie Zhan +Acked-by: Chanwoo Choi +Signed-off-by: Chanwoo Choi +Link: https://patchwork.kernel.org/project/linux-pm/patch/20250915062135.748653-1-zhangpengjie2@huawei.com/ +Signed-off-by: Sasha Levin +--- + drivers/devfreq/hisi_uncore_freq.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/devfreq/hisi_uncore_freq.c b/drivers/devfreq/hisi_uncore_freq.c +index 96d1815059e32..c1ed70fa0a400 100644 +--- a/drivers/devfreq/hisi_uncore_freq.c ++++ b/drivers/devfreq/hisi_uncore_freq.c +@@ -265,10 +265,11 @@ static int hisi_uncore_target(struct device *dev, unsigned long *freq, + dev_err(dev, "Failed to get opp for freq %lu hz\n", *freq); + return PTR_ERR(opp); + } +- dev_pm_opp_put(opp); + + data = (u32)(dev_pm_opp_get_freq(opp) / HZ_PER_MHZ); + ++ dev_pm_opp_put(opp); ++ + return hisi_uncore_cmd_send(uncore, HUCF_PCC_CMD_SET_FREQ, &data); + } + +-- +2.51.0 + diff --git a/queue-6.18/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-6.18/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..5fa4394af4 --- /dev/null +++ b/queue-6.18/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From 6ab05b4fe5d52b10dd5018981641fcc5d75d5657 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9236e00785786..9933cdc5c387a 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -364,7 +364,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-6.18/power-supply-cw2015-check-devm_delayed_work_autocanc.patch b/queue-6.18/power-supply-cw2015-check-devm_delayed_work_autocanc.patch new file mode 100644 index 0000000000..0a02ba34b5 --- /dev/null +++ b/queue-6.18/power-supply-cw2015-check-devm_delayed_work_autocanc.patch @@ -0,0 +1,46 @@ +From 02753363238c832e470687d445bce9b83db7dc79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:07:11 +0300 +Subject: power: supply: cw2015: Check devm_delayed_work_autocancel() return + code + +From: Ivan Abramov + +[ Upstream commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 ] + +Since devm_delayed_work_autocancel() may fail, add return code check and +exit cw_bat_probe() on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/cw2015_battery.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 2263d5d3448fd..0806abea2372f 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -699,7 +699,13 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ if (ret) { ++ dev_err_probe(&client->dev, ret, ++ "Failed to register delayed work\n"); ++ return ret; ++ } ++ + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +-- +2.51.0 + diff --git a/queue-6.18/power-supply-max17040-check-iio_read_channel_process.patch b/queue-6.18/power-supply-max17040-check-iio_read_channel_process.patch new file mode 100644 index 0000000000..d22872008c --- /dev/null +++ b/queue-6.18/power-supply-max17040-check-iio_read_channel_process.patch @@ -0,0 +1,50 @@ +From 70c88a6a2ced0b278ff75f9d2a4a7c69f79ed814 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 16:36:47 +0300 +Subject: power: supply: max17040: Check iio_read_channel_processed() return + code + +From: Ivan Abramov + +[ Upstream commit 2c68ac48c52ad146523f32b01d70009622bf81aa ] + +Since iio_read_channel_processed() may fail, return its exit code on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 814755c48f8b ("power: max17040: get thermal data from adc if available") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008133648.559286-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/max17040_battery.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/max17040_battery.c b/drivers/power/supply/max17040_battery.c +index c1640bc6accd2..48453508688a4 100644 +--- a/drivers/power/supply/max17040_battery.c ++++ b/drivers/power/supply/max17040_battery.c +@@ -388,6 +388,7 @@ static int max17040_get_property(struct power_supply *psy, + union power_supply_propval *val) + { + struct max17040_chip *chip = power_supply_get_drvdata(psy); ++ int ret; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: +@@ -410,7 +411,10 @@ static int max17040_get_property(struct power_supply *psy, + if (!chip->channel_temp) + return -ENODATA; + +- iio_read_channel_processed(chip->channel_temp, &val->intval); ++ ret = iio_read_channel_processed(chip->channel_temp, &val->intval); ++ if (ret) ++ return ret; ++ + val->intval /= 100; /* Convert from milli- to deci-degree */ + + break; +-- +2.51.0 + diff --git a/queue-6.18/power-supply-qcom_battmgr-clamp-charge-control-thres.patch b/queue-6.18/power-supply-qcom_battmgr-clamp-charge-control-thres.patch new file mode 100644 index 0000000000..883d1c272d --- /dev/null +++ b/queue-6.18/power-supply-qcom_battmgr-clamp-charge-control-thres.patch @@ -0,0 +1,59 @@ +From fac3d8a4d632b103d748e5e0f0ea17cc141207a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 20:32:18 -0300 +Subject: power: supply: qcom_battmgr: clamp charge control thresholds + +From: Val Packett + +[ Upstream commit 8809980fdc8a86070667032fa4005ee83f1c62f3 ] + +The sysfs API documentation says that drivers "round written values to +the nearest supported value" for charge_control_end_threshold. + +Let's do this for both thresholds, as userspace (e.g. upower) generally +does not expect these writes to fail at all. + +Fixes: cc3e883a0625 ("power: supply: qcom_battmgr: Add charge control support") +Signed-off-by: Val Packett +Link: https://patch.msgid.link/20251012233333.19144-3-val@packett.cool +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/qcom_battmgr.c | 14 ++------------ + 1 file changed, 2 insertions(+), 12 deletions(-) + +diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c +index 3c2837ef34617..c8028606bba00 100644 +--- a/drivers/power/supply/qcom_battmgr.c ++++ b/drivers/power/supply/qcom_battmgr.c +@@ -678,12 +678,7 @@ static int qcom_battmgr_set_charge_start_threshold(struct qcom_battmgr *battmgr, + u32 target_soc, delta_soc; + int ret; + +- if (start_soc < CHARGE_CTRL_START_THR_MIN || +- start_soc > CHARGE_CTRL_START_THR_MAX) { +- dev_err(battmgr->dev, "charge control start threshold exceed range: [%u - %u]\n", +- CHARGE_CTRL_START_THR_MIN, CHARGE_CTRL_START_THR_MAX); +- return -EINVAL; +- } ++ start_soc = clamp(start_soc, CHARGE_CTRL_START_THR_MIN, CHARGE_CTRL_START_THR_MAX); + + /* + * If the new start threshold is larger than the old end threshold, +@@ -716,12 +711,7 @@ static int qcom_battmgr_set_charge_end_threshold(struct qcom_battmgr *battmgr, i + u32 delta_soc = CHARGE_CTRL_DELTA_SOC; + int ret; + +- if (end_soc < CHARGE_CTRL_END_THR_MIN || +- end_soc > CHARGE_CTRL_END_THR_MAX) { +- dev_err(battmgr->dev, "charge control end threshold exceed range: [%u - %u]\n", +- CHARGE_CTRL_END_THR_MIN, CHARGE_CTRL_END_THR_MAX); +- return -EINVAL; +- } ++ end_soc = clamp(end_soc, CHARGE_CTRL_END_THR_MIN, CHARGE_CTRL_END_THR_MAX); + + if (battmgr->info.charge_ctrl_start && end_soc > battmgr->info.charge_ctrl_start) + delta_soc = end_soc - battmgr->info.charge_ctrl_start; +-- +2.51.0 + diff --git a/queue-6.18/power-supply-qcom_battmgr-support-disabling-charge-c.patch b/queue-6.18/power-supply-qcom_battmgr-support-disabling-charge-c.patch new file mode 100644 index 0000000000..4e06d312d2 --- /dev/null +++ b/queue-6.18/power-supply-qcom_battmgr-support-disabling-charge-c.patch @@ -0,0 +1,92 @@ +From 3d01f4e420e6e7624d713557a37f5b38170a631f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 20:32:19 -0300 +Subject: power: supply: qcom_battmgr: support disabling charge control + +From: Val Packett + +[ Upstream commit 446fcf494691da4e685923e5fad02b163955fc0e ] + +Existing userspace (in particular, upower) disables charge control by +setting the start threshold to 0 and the stop threshold to 100. + +Handle that by actually setting the enable bit to 0 when a start +threshold of 0 was requested. + +Fixes: cc3e883a0625 ("power: supply: qcom_battmgr: Add charge control support") +Signed-off-by: Val Packett +Link: https://patch.msgid.link/20251012233333.19144-4-val@packett.cool +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/qcom_battmgr.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/power/supply/qcom_battmgr.c b/drivers/power/supply/qcom_battmgr.c +index c8028606bba00..e6f01e0122e1c 100644 +--- a/drivers/power/supply/qcom_battmgr.c ++++ b/drivers/power/supply/qcom_battmgr.c +@@ -257,6 +257,7 @@ struct qcom_battmgr_info { + unsigned int capacity_warning; + unsigned int cycle_count; + unsigned int charge_count; ++ bool charge_ctrl_enable; + unsigned int charge_ctrl_start; + unsigned int charge_ctrl_end; + char model_number[BATTMGR_STRING_LEN]; +@@ -659,13 +660,13 @@ static int qcom_battmgr_bat_get_property(struct power_supply *psy, + } + + static int qcom_battmgr_set_charge_control(struct qcom_battmgr *battmgr, +- u32 target_soc, u32 delta_soc) ++ bool enable, u32 target_soc, u32 delta_soc) + { + struct qcom_battmgr_charge_ctrl_request request = { + .hdr.owner = cpu_to_le32(PMIC_GLINK_OWNER_BATTMGR), + .hdr.type = cpu_to_le32(PMIC_GLINK_REQ_RESP), + .hdr.opcode = cpu_to_le32(BATTMGR_CHG_CTRL_LIMIT_EN), +- .enable = cpu_to_le32(1), ++ .enable = cpu_to_le32(enable), + .target_soc = cpu_to_le32(target_soc), + .delta_soc = cpu_to_le32(delta_soc), + }; +@@ -677,6 +678,7 @@ static int qcom_battmgr_set_charge_start_threshold(struct qcom_battmgr *battmgr, + { + u32 target_soc, delta_soc; + int ret; ++ bool enable = start_soc != 0; + + start_soc = clamp(start_soc, CHARGE_CTRL_START_THR_MIN, CHARGE_CTRL_START_THR_MAX); + +@@ -696,9 +698,10 @@ static int qcom_battmgr_set_charge_start_threshold(struct qcom_battmgr *battmgr, + } + + mutex_lock(&battmgr->lock); +- ret = qcom_battmgr_set_charge_control(battmgr, target_soc, delta_soc); ++ ret = qcom_battmgr_set_charge_control(battmgr, enable, target_soc, delta_soc); + mutex_unlock(&battmgr->lock); + if (!ret) { ++ battmgr->info.charge_ctrl_enable = enable; + battmgr->info.charge_ctrl_start = start_soc; + battmgr->info.charge_ctrl_end = target_soc; + } +@@ -710,6 +713,7 @@ static int qcom_battmgr_set_charge_end_threshold(struct qcom_battmgr *battmgr, i + { + u32 delta_soc = CHARGE_CTRL_DELTA_SOC; + int ret; ++ bool enable = battmgr->info.charge_ctrl_enable; + + end_soc = clamp(end_soc, CHARGE_CTRL_END_THR_MIN, CHARGE_CTRL_END_THR_MAX); + +@@ -717,7 +721,7 @@ static int qcom_battmgr_set_charge_end_threshold(struct qcom_battmgr *battmgr, i + delta_soc = end_soc - battmgr->info.charge_ctrl_start; + + mutex_lock(&battmgr->lock); +- ret = qcom_battmgr_set_charge_control(battmgr, end_soc, delta_soc); ++ ret = qcom_battmgr_set_charge_control(battmgr, enable, end_soc, delta_soc); + mutex_unlock(&battmgr->lock); + if (!ret) { + battmgr->info.charge_ctrl_start = end_soc - delta_soc; +-- +2.51.0 + diff --git a/queue-6.18/power-supply-rt5033_charger-fix-device-node-referenc.patch b/queue-6.18/power-supply-rt5033_charger-fix-device-node-referenc.patch new file mode 100644 index 0000000000..b64ab4896e --- /dev/null +++ b/queue-6.18/power-supply-rt5033_charger-fix-device-node-referenc.patch @@ -0,0 +1,41 @@ +From 6614ee48895ed6e3a3a6ea9f814fadc37fc74131 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 19:32:34 +0800 +Subject: power: supply: rt5033_charger: Fix device node reference leaks + +From: Haotian Zhang + +[ Upstream commit 6cdc4d488c2f3a61174bfba4e8cc4ac92c219258 ] + +The device node pointers `np_conn` and `np_edev`, obtained from +of_parse_phandle() and of_get_parent() respectively, are not released. +This results in a reference count leak. + +Add of_node_put() calls after the last use of these device nodes to +properly release their references and fix the leaks. + +Fixes: 8242336dc8a8 ("power: supply: rt5033_charger: Add cable detection and USB OTG supply") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20250929113234.1726-1-vulab@iscas.ac.cn +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt5033_charger.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/power/supply/rt5033_charger.c b/drivers/power/supply/rt5033_charger.c +index 2fdc584397075..de724f23e453b 100644 +--- a/drivers/power/supply/rt5033_charger.c ++++ b/drivers/power/supply/rt5033_charger.c +@@ -701,6 +701,8 @@ static int rt5033_charger_probe(struct platform_device *pdev) + np_conn = of_parse_phandle(pdev->dev.of_node, "richtek,usb-connector", 0); + np_edev = of_get_parent(np_conn); + charger->edev = extcon_find_edev_by_node(np_edev); ++ of_node_put(np_edev); ++ of_node_put(np_conn); + if (IS_ERR(charger->edev)) { + dev_warn(charger->dev, "no extcon device found in device-tree\n"); + goto out; +-- +2.51.0 + diff --git a/queue-6.18/power-supply-rt9467-prevent-using-uninitialized-loca.patch b/queue-6.18/power-supply-rt9467-prevent-using-uninitialized-loca.patch new file mode 100644 index 0000000000..b3bf24ec4d --- /dev/null +++ b/queue-6.18/power-supply-rt9467-prevent-using-uninitialized-loca.patch @@ -0,0 +1,40 @@ +From 0b13728c74a5d3aee5b27ce05be980d9191998a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:53:08 +0300 +Subject: power: supply: rt9467: Prevent using uninitialized local variable in + rt9467_set_value_from_ranges() + +From: Murad Masimov + +[ Upstream commit 15aca30cc6c69806054b896a2ccf7577239cb878 ] + +There is a typo in rt9467_set_value_from_ranges() that can cause leaving local +variable sel with an undefined value which is then used in regmap_field_write(). + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Murad Masimov +Link: https://patch.msgid.link/20251009145308.1830893-1-m.masimov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index b4917514bd701..44c26fb37a775 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -376,7 +376,7 @@ static int rt9467_set_value_from_ranges(struct rt9467_chg_data *data, + if (rsel == RT9467_RANGE_VMIVR) { + ret = linear_range_get_selector_high(range, value, &sel, &found); + if (ret) +- value = range->max_sel; ++ sel = range->max_sel; + } else { + linear_range_get_selector_within(range, value, &sel); + } +-- +2.51.0 + diff --git a/queue-6.18/power-supply-rt9467-return-error-on-failure-in-rt946.patch b/queue-6.18/power-supply-rt9467-return-error-on-failure-in-rt946.patch new file mode 100644 index 0000000000..a8c6a87bc7 --- /dev/null +++ b/queue-6.18/power-supply-rt9467-return-error-on-failure-in-rt946.patch @@ -0,0 +1,44 @@ +From 21b5f8570d8710ec67959b495a864ad58f9e9d98 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:47:24 +0300 +Subject: power: supply: rt9467: Return error on failure in + rt9467_set_value_from_ranges() + +From: Ivan Abramov + +[ Upstream commit 8b27fe2d8d2380118c343629175385ff587e2fe4 ] + +The return value of rt9467_set_value_from_ranges() when setting AICL VTH is +not checked, even though it may fail. + +Log error and return from rt9467_run_aicl() on fail. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009144725.562278-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index fe773dd8b404f..b4917514bd701 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -588,6 +588,10 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) + aicl_vth = mivr_vth + RT9467_AICLVTH_GAP_uV; + ret = rt9467_set_value_from_ranges(data, F_AICL_VTH, + RT9467_RANGE_AICL_VTH, aicl_vth); ++ if (ret) { ++ dev_err(data->dev, "Failed to set AICL VTH\n"); ++ return ret; ++ } + + /* Trigger AICL function */ + ret = regmap_field_write(data->rm_field[F_AICL_MEAS], 1); +-- +2.51.0 + diff --git a/queue-6.18/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-6.18/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..84f4932cf0 --- /dev/null +++ b/queue-6.18/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From ad0173e71b8786c06a739ffe6c8864e380c93b60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 6acdba7885ca5..78fa0573ef25c 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.18/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-6.18/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..a9e46721d8 --- /dev/null +++ b/queue-6.18/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From ddcbe4ed194dc6604022f84d1697683c87ce5ad8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index f4a8c98772491..1beb578c64114 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -263,10 +263,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -306,10 +305,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-6.18/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch b/queue-6.18/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch new file mode 100644 index 0000000000..43ec3632af --- /dev/null +++ b/queue-6.18/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch @@ -0,0 +1,78 @@ +From ae5ccdbd7fcc22b5edcbb784c9303290e73d9127 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:27 +0530 +Subject: powerpc/64s/hash: Restrict stress_hpt_struct memblock region to + within RMA limit + +From: Ritesh Harjani (IBM) + +[ Upstream commit 17b45ccf09882e0c808ad2cf62acdc90ad968746 ] + +When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real +Addressing Mode during early boot. During this, we should ensure that +memory region allocations for stress_hpt_struct should happen from +within RMA region as otherwise the boot might get stuck while doing +memset of this region. + +History behind why do we have RMA region limitation is better explained +in these 2 patches [1] & [2]. This patch ensures that memset to +stress_hpt_struct during early boot does not cross ppc64_rma_size +boundary. + +[1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/ +[2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/ + +Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/hash_utils.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c +index 3aee3af614af8..c99be1286d517 100644 +--- a/arch/powerpc/mm/book3s64/hash_utils.c ++++ b/arch/powerpc/mm/book3s64/hash_utils.c +@@ -1302,11 +1302,14 @@ static void __init htab_initialize(void) + unsigned long table; + unsigned long pteg_count; + unsigned long prot; +- phys_addr_t base = 0, size = 0, end; ++ phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; + u64 i; + + DBG(" -> htab_initialize()\n"); + ++ if (firmware_has_feature(FW_FEATURE_LPAR)) ++ limit = ppc64_rma_size; ++ + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { + mmu_kernel_ssize = MMU_SEGSIZE_1T; + mmu_highuser_ssize = MMU_SEGSIZE_1T; +@@ -1322,7 +1325,7 @@ static void __init htab_initialize(void) + // Too early to use nr_cpu_ids, so use NR_CPUS + tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, + __alignof__(struct stress_hpt_struct), +- 0, MEMBLOCK_ALLOC_ANYWHERE); ++ MEMBLOCK_LOW_LIMIT, limit); + memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); + stress_hpt_struct = __va(tmp); + +@@ -1356,11 +1359,10 @@ static void __init htab_initialize(void) + mmu_hash_ops.hpte_clear_all(); + #endif + } else { +- unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; + + table = memblock_phys_alloc_range(htab_size_bytes, + htab_size_bytes, +- 0, limit); ++ MEMBLOCK_LOW_LIMIT, limit); + if (!table) + panic("ERROR: Failed to allocate %pa bytes below %pa\n", + &htab_size_bytes, &limit); +-- +2.51.0 + diff --git a/queue-6.18/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-6.18/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..016d787ccf --- /dev/null +++ b/queue-6.18/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From 8bcc81e722b1813874b4f8ec96601adc2f6807c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index a6baa6166d940..671d0dc00c6d0 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-6.18/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch b/queue-6.18/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch new file mode 100644 index 0000000000..33a6e125aa --- /dev/null +++ b/queue-6.18/powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch @@ -0,0 +1,83 @@ +From 2fd91c8663944e7a352be5202e9b107bc628e5db Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 09:09:41 +0530 +Subject: powerpc/kdump: Fix size calculation for hot-removed memory ranges + +From: Sourabh Jain + +[ Upstream commit 7afe2383eff05f76f4ce2cfda658b7889c89f101 ] + +The elfcorehdr segment in the kdump image stores information about the +memory regions (called crash memory ranges) that the kdump kernel must +capture. + +When a memory hot-remove event occurs, the kernel regenerates the +elfcorehdr for the currently loaded kdump image to remove the +hot-removed memory from the crash memory ranges. + +Call chain: +remove_mem_range() +update_crash_elfcorehdr() +arch_crash_handle_hotplug_event() +crash_handle_hotplug_event() + +While removing the hot-removed memory from the crash memory ranges in +remove_mem_range(), if the removed memory lies within an existing crash +range, that range is split into two. During this split, the size of the +second range was being calculated incorrectly. + +This leads to dump capture failure with makedumpfile with below error: + +$ makedumpfile -l -d 31 /proc/vmcore /tmp/vmcore + +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:16 +validate_mem_section: Can't read mem_section array. +readpage_elf: Attempt to read non-existent page at 0xbbdab0000. +readmem: type_addr: 0, addr:c000000bbdab7f00, size:8 +get_mm_sparsemem: Can't get the address of mem_section. + +The updated crash memory range in PT_LOAD entry is holding incorrect +data (checkout FileSiz and MemSiz): + +readelf -a /proc/vmcore + + Type Offset VirtAddr PhysAddr + FileSiz MemSiz Flags Align + LOAD 0x0000000b013d0000 0xc000000b80000000 0x0000000b80000000 + 0xffffffffc0000000 0xffffffffc0000000 RWE 0x0 + + +Update the size calculation for the new crash memory range to fix this +issue. + +Note: This problem will not occur if the kdump kernel is loaded or +reloaded after a memory hot-remove operation. + +Fixes: 849599b702ef ("powerpc/crash: add crash memory hotplug support") +Reported-by: Shirisha G +Signed-off-by: Sourabh Jain +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20251105033941.1752287-1-sourabhjain@linux.ibm.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/kexec/ranges.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kexec/ranges.c b/arch/powerpc/kexec/ranges.c +index 3702b0bdab141..426bdca4667e7 100644 +--- a/arch/powerpc/kexec/ranges.c ++++ b/arch/powerpc/kexec/ranges.c +@@ -697,8 +697,8 @@ int remove_mem_range(struct crash_mem **mem_ranges, u64 base, u64 size) + * two half. + */ + else { ++ size = mem_rngs->ranges[i].end - end + 1; + mem_rngs->ranges[i].end = base - 1; +- size = mem_rngs->ranges[i].end - end; + ret = add_mem_range(mem_ranges, end + 1, size); + } + } +-- +2.51.0 + diff --git a/queue-6.18/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-6.18/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..03e8ff207a --- /dev/null +++ b/queue-6.18/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From 2e692e8b517008d80b449342b4d26a4477a09049 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index dc9e4a14b8854..8892f218a8147 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-6.18/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-6.18/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..a3943a52e1 --- /dev/null +++ b/queue-6.18/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From d915e9fa1cebb3f867968994163d744b5e78d1f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index 578e95e0296c6..532903da521fd 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -34,29 +34,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return pwmchip_get_drvdata(chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -102,6 +79,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -119,8 +99,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + }; + +-- +2.51.0 + diff --git a/queue-6.18/pwm-simplify-printf-to-emit-chip-npwm-in-debugfs-pwm.patch b/queue-6.18/pwm-simplify-printf-to-emit-chip-npwm-in-debugfs-pwm.patch new file mode 100644 index 0000000000..d81ef62afe --- /dev/null +++ b/queue-6.18/pwm-simplify-printf-to-emit-chip-npwm-in-debugfs-pwm.patch @@ -0,0 +1,52 @@ +From 28dac19c7fb64cd5de30e3871932930a48a7231f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 18:57:03 +0200 +Subject: pwm: Simplify printf to emit chip->npwm in $debugfs/pwm +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 3cf8e55894b51c14f8500cae5e68ed48b1b0f3fd ] + +Instead of caring to correctly pluralize "PWM device(s)" using + + (chip->npwm != 1) ? "s" : "" + +or + + str_plural(chip->npwm) + +just simplify the format to not need a plural-s. + +Signed-off-by: Uwe Kleine-König +Link: https://patch.msgid.link/20250926165702.321514-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Stable-dep-of: 5f7ff902e7f3 ("pwm: Use %u to printf unsigned int pwm_chip::npwm and pwm_chip::id") +Signed-off-by: Sasha Levin +--- + drivers/pwm/core.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c +index ea2ccf42e8144..5b75f4a084967 100644 +--- a/drivers/pwm/core.c ++++ b/drivers/pwm/core.c +@@ -2696,11 +2696,10 @@ static int pwm_seq_show(struct seq_file *s, void *v) + { + struct pwm_chip *chip = v; + +- seq_printf(s, "%s%d: %s/%s, %d PWM device%s\n", ++ seq_printf(s, "%s%d: %s/%s, npwm: %d\n", + (char *)s->private, chip->id, + pwmchip_parent(chip)->bus ? pwmchip_parent(chip)->bus->name : "no-bus", +- dev_name(pwmchip_parent(chip)), chip->npwm, +- (chip->npwm != 1) ? "s" : ""); ++ dev_name(pwmchip_parent(chip)), chip->npwm); + + pwm_dbg_show(chip, s); + +-- +2.51.0 + diff --git a/queue-6.18/pwm-use-u-to-printf-unsigned-int-pwm_chip-npwm-and-p.patch b/queue-6.18/pwm-use-u-to-printf-unsigned-int-pwm_chip-npwm-and-p.patch new file mode 100644 index 0000000000..cbfc92d636 --- /dev/null +++ b/queue-6.18/pwm-use-u-to-printf-unsigned-int-pwm_chip-npwm-and-p.patch @@ -0,0 +1,40 @@ +From 7a5394d5456d30970eda703347afd96e1e28ad42 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 6 Oct 2025 15:35:26 +0200 +Subject: pwm: Use %u to printf unsigned int pwm_chip::npwm and pwm_chip::id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 5f7ff902e7f324c10f2b64c5ba2e5e2d0bc4e07e ] + +%u is the right conversion specifier to emit an unsigned int value. + +Fixes: 62099abf67a2 ("pwm: Add debugfs interface") +Fixes: 0360a4873372 ("pwm: Mention PWM chip ID in /sys/kernel/debug/pwm") +Signed-off-by: Uwe Kleine-König +Link: https://patch.msgid.link/20251006133525.2457171-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c +index 5b75f4a084967..7dd1cf2ba4025 100644 +--- a/drivers/pwm/core.c ++++ b/drivers/pwm/core.c +@@ -2696,7 +2696,7 @@ static int pwm_seq_show(struct seq_file *s, void *v) + { + struct pwm_chip *chip = v; + +- seq_printf(s, "%s%d: %s/%s, npwm: %d\n", ++ seq_printf(s, "%s%u: %s/%s, npwm: %u\n", + (char *)s->private, chip->id, + pwmchip_parent(chip)->bus ? pwmchip_parent(chip)->bus->name : "no-bus", + dev_name(pwmchip_parent(chip)), chip->npwm); +-- +2.51.0 + diff --git a/queue-6.18/random-use-offstack-cpumask-when-necessary.patch b/queue-6.18/random-use-offstack-cpumask-when-necessary.patch new file mode 100644 index 0000000000..6f7378da03 --- /dev/null +++ b/queue-6.18/random-use-offstack-cpumask-when-necessary.patch @@ -0,0 +1,94 @@ +From 797e29a85795aa53ab0fba8de486886e5d224ef5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Jun 2025 11:27:08 +0200 +Subject: random: use offstack cpumask when necessary + +From: Arnd Bergmann + +[ Upstream commit 5d49f1a5bd358d24e5f88b23b46da833de1dbec8 ] + +The entropy generation function keeps a local cpu mask on the stack, +which can trigger warnings in configurations with a large number of +CPUs: + + drivers/char/random.c:1292:20: error: stack frame size (1288) + exceeds limit (1280) in 'try_to_generate_entropy' [-Werror,-Wframe-larger-than] + +Use the cpumask interface to dynamically allocate it in those +configurations. + +Fixes: 1c21fe00eda7 ("random: spread out jitter callback to different CPUs") +Signed-off-by: Arnd Bergmann +Signed-off-by: Jason A. Donenfeld +Signed-off-by: Sasha Levin +--- + drivers/char/random.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/char/random.c b/drivers/char/random.c +index b8b24b6ed3fe4..4ba5f0c4c8b24 100644 +--- a/drivers/char/random.c ++++ b/drivers/char/random.c +@@ -1296,6 +1296,7 @@ static void __cold try_to_generate_entropy(void) + struct entropy_timer_state *stack = PTR_ALIGN((void *)stack_bytes, SMP_CACHE_BYTES); + unsigned int i, num_different = 0; + unsigned long last = random_get_entropy(); ++ cpumask_var_t timer_cpus; + int cpu = -1; + + for (i = 0; i < NUM_TRIAL_SAMPLES - 1; ++i) { +@@ -1310,13 +1311,15 @@ static void __cold try_to_generate_entropy(void) + + atomic_set(&stack->samples, 0); + timer_setup_on_stack(&stack->timer, entropy_timer, 0); ++ if (!alloc_cpumask_var(&timer_cpus, GFP_KERNEL)) ++ goto out; ++ + while (!crng_ready() && !signal_pending(current)) { + /* + * Check !timer_pending() and then ensure that any previous callback has finished + * executing by checking timer_delete_sync_try(), before queueing the next one. + */ + if (!timer_pending(&stack->timer) && timer_delete_sync_try(&stack->timer) >= 0) { +- struct cpumask timer_cpus; + unsigned int num_cpus; + + /* +@@ -1326,19 +1329,19 @@ static void __cold try_to_generate_entropy(void) + preempt_disable(); + + /* Only schedule callbacks on timer CPUs that are online. */ +- cpumask_and(&timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); +- num_cpus = cpumask_weight(&timer_cpus); ++ cpumask_and(timer_cpus, housekeeping_cpumask(HK_TYPE_TIMER), cpu_online_mask); ++ num_cpus = cpumask_weight(timer_cpus); + /* In very bizarre case of misconfiguration, fallback to all online. */ + if (unlikely(num_cpus == 0)) { +- timer_cpus = *cpu_online_mask; +- num_cpus = cpumask_weight(&timer_cpus); ++ *timer_cpus = *cpu_online_mask; ++ num_cpus = cpumask_weight(timer_cpus); + } + + /* Basic CPU round-robin, which avoids the current CPU. */ + do { +- cpu = cpumask_next(cpu, &timer_cpus); ++ cpu = cpumask_next(cpu, timer_cpus); + if (cpu >= nr_cpu_ids) +- cpu = cpumask_first(&timer_cpus); ++ cpu = cpumask_first(timer_cpus); + } while (cpu == smp_processor_id() && num_cpus > 1); + + /* Expiring the timer at `jiffies` means it's the next tick. */ +@@ -1354,6 +1357,8 @@ static void __cold try_to_generate_entropy(void) + } + mix_pool_bytes(&stack->entropy, sizeof(stack->entropy)); + ++ free_cpumask_var(timer_cpus); ++out: + timer_delete_sync(&stack->timer); + timer_destroy_on_stack(&stack->timer); + } +-- +2.51.0 + diff --git a/queue-6.18/ras-report-all-arm-processor-cper-information-to-use.patch b/queue-6.18/ras-report-all-arm-processor-cper-information-to-use.patch new file mode 100644 index 0000000000..f8919a3e5c --- /dev/null +++ b/queue-6.18/ras-report-all-arm-processor-cper-information-to-use.patch @@ -0,0 +1,308 @@ +From 6c7cd89aeadf0e9e63dacd14f94d38c5408ee99d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 14 Aug 2025 09:52:52 -0700 +Subject: RAS: Report all ARM processor CPER information to userspace + +From: Jason Tian + +[ Upstream commit 05954511b73e748d0370549ad9dd9cd95297d97a ] + +The ARM processor CPER record was added in UEFI v2.6 and remained +unchanged up to v2.10. + +Yet, the original arm_event trace code added by + + e9279e83ad1f ("trace, ras: add ARM processor error trace event") + +is incomplete, as it only traces some fields of UAPI 2.6 table N.16, not +exporting any information from tables N.17 to N.29 of the record. + +This is not enough for the user to be able to figure out what has +exactly happened or to take appropriate action. + +According to the UEFI v2.9 specification chapter N2.4.4, the ARM +processor error section includes: + +- several (ERR_INFO_NUM) ARM processor error information structures + (Tables N.17 to N.20); +- several (CONTEXT_INFO_NUM) ARM processor context information + structures (Tables N.21 to N.29); +- several vendor specific error information structures. The + size is given by Section Length minus the size of the other + fields. + +In addition, it also exports two fields that are parsed by the GHES +driver when firmware reports it, e.g.: + +- error severity +- CPU logical index + +Report all of these information to userspace via a the ARM tracepoint so +that userspace can properly record the error and take decisions related +to CPU core isolation according to error severity and other info. + +The updated ARM trace event now contains the following fields: + +====================================== ============================= +UEFI field on table N.16 ARM Processor trace fields +====================================== ============================= +Validation handled when filling data for + affinity MPIDR and running + state. +ERR_INFO_NUM pei_len +CONTEXT_INFO_NUM ctx_len +Section Length indirectly reported by + pei_len, ctx_len and oem_len +Error affinity level affinity +MPIDR_EL1 mpidr +MIDR_EL1 midr +Running State running_state +PSCI State psci_state +Processor Error Information Structure pei_err - count at pei_len +Processor Context ctx_err- count at ctx_len +Vendor Specific Error Info oem - count at oem_len +====================================== ============================= + +It should be noted that decoding of tables N.17 to N.29, if needed, will +be handled in userspace. That gives more flexibility, as there won't be +any need to flood the kernel with micro-architecture specific error +decoding. + +Also, decoding the other fields require a complex logic, and should be +done for each of the several values inside the record field. So, let +userspace daemons like rasdaemon decode them, parsing such tables and +having vendor-specific micro-architecture-specific decoders. + + [mchehab: modified description, solved merge conflicts and fixed coding style] + +Signed-off-by: Jason Tian +Co-developed-by: Shengwei Luo +Signed-off-by: Shengwei Luo +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Daniel Ferguson # rebased +Reviewed-by: Jonathan Cameron +Tested-by: Shiju Jose +Acked-by: Borislav Petkov (AMD) +Fixes: e9279e83ad1f ("trace, ras: add ARM processor error trace event") +Link: https://uefi.org/specs/UEFI/2.10/Apx_N_Common_Platform_Error_Record.html#arm-processor-error-section +Signed-off-by: Ard Biesheuvel +Signed-off-by: Sasha Levin +--- + drivers/acpi/apei/ghes.c | 11 ++++----- + drivers/ras/ras.c | 40 ++++++++++++++++++++++++++++++-- + include/linux/ras.h | 16 ++++++++++--- + include/ras/ras_event.h | 49 ++++++++++++++++++++++++++++++++++++---- + 4 files changed, 99 insertions(+), 17 deletions(-) + +diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c +index 97ee19f2cae06..7d2466b515046 100644 +--- a/drivers/acpi/apei/ghes.c ++++ b/drivers/acpi/apei/ghes.c +@@ -552,7 +552,7 @@ static bool ghes_handle_memory_failure(struct acpi_hest_generic_data *gdata, + } + + static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, +- int sev, bool sync) ++ int sev, bool sync) + { + struct cper_sec_proc_arm *err = acpi_hest_get_payload(gdata); + int flags = sync ? MF_ACTION_REQUIRED : 0; +@@ -560,9 +560,8 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata, + int sec_sev, i; + char *p; + +- log_arm_hw_error(err); +- + sec_sev = ghes_severity(gdata->error_severity); ++ log_arm_hw_error(err, sec_sev); + if (sev != GHES_SEV_RECOVERABLE || sec_sev != GHES_SEV_RECOVERABLE) + return false; + +@@ -895,11 +894,9 @@ static void ghes_do_proc(struct ghes *ghes, + + arch_apei_report_mem_error(sev, mem_err); + queued = ghes_handle_memory_failure(gdata, sev, sync); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PCIE)) { + ghes_handle_aer(gdata); +- } +- else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { ++ } else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) { + queued = ghes_handle_arm_hw_error(gdata, sev, sync); + } else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) { + struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata); +diff --git a/drivers/ras/ras.c b/drivers/ras/ras.c +index ac0e132ccc3eb..2a5b5a9fdcb36 100644 +--- a/drivers/ras/ras.c ++++ b/drivers/ras/ras.c +@@ -53,9 +53,45 @@ void log_non_standard_event(const guid_t *sec_type, const guid_t *fru_id, + } + EXPORT_SYMBOL_GPL(log_non_standard_event); + +-void log_arm_hw_error(struct cper_sec_proc_arm *err) ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) + { +- trace_arm_event(err); ++ struct cper_arm_err_info *err_info; ++ struct cper_arm_ctx_info *ctx_info; ++ u8 *ven_err_data; ++ u32 ctx_len = 0; ++ int n, sz, cpu; ++ s32 vsei_len; ++ u32 pei_len; ++ u8 *pei_err, *ctx_err; ++ ++ pei_len = sizeof(struct cper_arm_err_info) * err->err_info_num; ++ pei_err = (u8 *)(err + 1); ++ ++ err_info = (struct cper_arm_err_info *)(err + 1); ++ ctx_info = (struct cper_arm_ctx_info *)(err_info + err->err_info_num); ++ ctx_err = (u8 *)ctx_info; ++ ++ for (n = 0; n < err->context_info_num; n++) { ++ sz = sizeof(struct cper_arm_ctx_info) + ctx_info->size; ++ ctx_info = (struct cper_arm_ctx_info *)((long)ctx_info + sz); ++ ctx_len += sz; ++ } ++ ++ vsei_len = err->section_length - (sizeof(struct cper_sec_proc_arm) + pei_len + ctx_len); ++ if (vsei_len < 0) { ++ pr_warn(FW_BUG "section length: %d\n", err->section_length); ++ pr_warn(FW_BUG "section length is too small\n"); ++ pr_warn(FW_BUG "firmware-generated error record is incorrect\n"); ++ vsei_len = 0; ++ } ++ ven_err_data = (u8 *)ctx_info; ++ ++ cpu = GET_LOGICAL_INDEX(err->mpidr); ++ if (cpu < 0) ++ cpu = -1; ++ ++ trace_arm_event(err, pei_err, pei_len, ctx_err, ctx_len, ++ ven_err_data, (u32)vsei_len, sev, cpu); + } + + static int __init ras_init(void) +diff --git a/include/linux/ras.h b/include/linux/ras.h +index a64182bc72ad3..468941bfe855f 100644 +--- a/include/linux/ras.h ++++ b/include/linux/ras.h +@@ -24,8 +24,7 @@ int __init parse_cec_param(char *str); + void log_non_standard_event(const guid_t *sec_type, + const guid_t *fru_id, const char *fru_text, + const u8 sev, const u8 *err, const u32 len); +-void log_arm_hw_error(struct cper_sec_proc_arm *err); +- ++void log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev); + #else + static inline void + log_non_standard_event(const guid_t *sec_type, +@@ -33,7 +32,7 @@ log_non_standard_event(const guid_t *sec_type, + const u8 sev, const u8 *err, const u32 len) + { return; } + static inline void +-log_arm_hw_error(struct cper_sec_proc_arm *err) { return; } ++log_arm_hw_error(struct cper_sec_proc_arm *err, const u8 sev) { return; } + #endif + + struct atl_err { +@@ -53,4 +52,15 @@ static inline unsigned long + amd_convert_umc_mca_addr_to_sys_addr(struct atl_err *err) { return -EINVAL; } + #endif /* CONFIG_AMD_ATL */ + ++#if defined(CONFIG_ARM) || defined(CONFIG_ARM64) ++#include ++/* ++ * Include ARM-specific SMP header which provides a function mapping mpidr to ++ * CPU logical index. ++ */ ++#define GET_LOGICAL_INDEX(mpidr) get_logical_index(mpidr & MPIDR_HWID_BITMASK) ++#else ++#define GET_LOGICAL_INDEX(mpidr) -EINVAL ++#endif /* CONFIG_ARM || CONFIG_ARM64 */ ++ + #endif /* __RAS_H__ */ +diff --git a/include/ras/ras_event.h b/include/ras/ras_event.h +index c8cd0f00c8454..c9f0b1018bcce 100644 +--- a/include/ras/ras_event.h ++++ b/include/ras/ras_event.h +@@ -168,11 +168,25 @@ TRACE_EVENT(mc_event, + * This event is generated when hardware detects an ARM processor error + * has occurred. UEFI 2.6 spec section N.2.4.4. + */ ++#define APEIL "ARM Processor Err Info data len" ++#define APEID "ARM Processor Err Info raw data" ++#define APECIL "ARM Processor Err Context Info data len" ++#define APECID "ARM Processor Err Context Info raw data" ++#define VSEIL "Vendor Specific Err Info data len" ++#define VSEID "Vendor Specific Err Info raw data" + TRACE_EVENT(arm_event, + +- TP_PROTO(const struct cper_sec_proc_arm *proc), ++ TP_PROTO(const struct cper_sec_proc_arm *proc, ++ const u8 *pei_err, ++ const u32 pei_len, ++ const u8 *ctx_err, ++ const u32 ctx_len, ++ const u8 *oem, ++ const u32 oem_len, ++ u8 sev, ++ int cpu), + +- TP_ARGS(proc), ++ TP_ARGS(proc, pei_err, pei_len, ctx_err, ctx_len, oem, oem_len, sev, cpu), + + TP_STRUCT__entry( + __field(u64, mpidr) +@@ -180,6 +194,14 @@ TRACE_EVENT(arm_event, + __field(u32, running_state) + __field(u32, psci_state) + __field(u8, affinity) ++ __field(u32, pei_len) ++ __dynamic_array(u8, pei_buf, pei_len) ++ __field(u32, ctx_len) ++ __dynamic_array(u8, ctx_buf, ctx_len) ++ __field(u32, oem_len) ++ __dynamic_array(u8, oem_buf, oem_len) ++ __field(u8, sev) ++ __field(int, cpu) + ), + + TP_fast_assign( +@@ -199,12 +221,29 @@ TRACE_EVENT(arm_event, + __entry->running_state = ~0; + __entry->psci_state = ~0; + } ++ __entry->pei_len = pei_len; ++ memcpy(__get_dynamic_array(pei_buf), pei_err, pei_len); ++ __entry->ctx_len = ctx_len; ++ memcpy(__get_dynamic_array(ctx_buf), ctx_err, ctx_len); ++ __entry->oem_len = oem_len; ++ memcpy(__get_dynamic_array(oem_buf), oem, oem_len); ++ __entry->sev = sev; ++ __entry->cpu = cpu; + ), + +- TP_printk("affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " +- "running state: %d; PSCI state: %d", ++ TP_printk("cpu: %d; error: %d; affinity level: %d; MPIDR: %016llx; MIDR: %016llx; " ++ "running state: %d; PSCI state: %d; " ++ "%s: %d; %s: %s; %s: %d; %s: %s; %s: %d; %s: %s", ++ __entry->cpu, ++ __entry->sev, + __entry->affinity, __entry->mpidr, __entry->midr, +- __entry->running_state, __entry->psci_state) ++ __entry->running_state, __entry->psci_state, ++ APEIL, __entry->pei_len, APEID, ++ __print_hex(__get_dynamic_array(pei_buf), __entry->pei_len), ++ APECIL, __entry->ctx_len, APECID, ++ __print_hex(__get_dynamic_array(ctx_buf), __entry->ctx_len), ++ VSEIL, __entry->oem_len, VSEID, ++ __print_hex(__get_dynamic_array(oem_buf), __entry->oem_len)) + ); + + /* +-- +2.51.0 + diff --git a/queue-6.18/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch b/queue-6.18/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch new file mode 100644 index 0000000000..9cdd59061b --- /dev/null +++ b/queue-6.18/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch @@ -0,0 +1,40 @@ +From 3c346a8374f993b323549da978c0d5ff03c351b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:54 -0800 +Subject: RDMA/bnxt_re: Fix the inline size for GenP7 devices + +From: Selvin Xavier + +[ Upstream commit 6afe40ff484a1155b71158b911c65299496e35c3 ] + +Inline size supported by the device is based on the number +of SGEs supported by the adapter. Change the inline +size calculation based on that. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kashyap Desai +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 9ef581ed785c8..a9afac2cbb7cf 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -162,7 +162,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw) + attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1; + attr->max_srq_sges = sb->max_srq_sge; + attr->max_pkey = 1; +- attr->max_inline_data = le32_to_cpu(sb->max_inline_data); ++ attr->max_inline_data = attr->max_qp_sges * sizeof(struct sq_sge); + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) + attr->l2_db_size = (sb->l2_db_space_size + 1) * + (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); +-- +2.51.0 + diff --git a/queue-6.18/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch b/queue-6.18/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch new file mode 100644 index 0000000000..63a4f62f40 --- /dev/null +++ b/queue-6.18/rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch @@ -0,0 +1,109 @@ +From 1de7f726d1039f738117670803062ed37ef72d82 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:55 -0800 +Subject: RDMA/bnxt_re: Pass correct flag for dma mr creation + +From: Selvin Xavier + +[ Upstream commit a26c4c7cdb50247b8486f1caa1ea8ab5e5c37edf ] + +DMA MR doesn't use the unified MR model. So the lkey passed +on to the reg_mr command to FW should contain the correct +lkey. Driver is incorrectly over writing the lkey with pdid +and firmware commands fails due to this. + +Avoid passing the wrong key for cases where the unified MR +registration is not used. + +Fixes: f786eebbbefa ("RDMA/bnxt_re: Avoid an extra hwrm per MR creation") +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-2-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 +++++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 6 +++--- + drivers/infiniband/hw/bnxt_re/qplib_sp.h | 2 +- + 3 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/ib_verbs.c b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +index 84ce3fce2826b..f19b55c13d580 100644 +--- a/drivers/infiniband/hw/bnxt_re/ib_verbs.c ++++ b/drivers/infiniband/hw/bnxt_re/ib_verbs.c +@@ -601,7 +601,8 @@ static int bnxt_re_create_fence_mr(struct bnxt_re_pd *pd) + mr->qplib_mr.va = (u64)(unsigned long)fence->va; + mr->qplib_mr.total_size = BNXT_RE_FENCE_BYTES; + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, +- BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE); ++ BNXT_RE_FENCE_PBL_SIZE, PAGE_SIZE, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register fence-MR\n"); + goto fail; +@@ -4027,7 +4028,7 @@ struct ib_mr *bnxt_re_get_dma_mr(struct ib_pd *ib_pd, int mr_access_flags) + mr->qplib_mr.hwq.level = PBL_LVL_MAX; + mr->qplib_mr.total_size = -1; /* Infinte length */ + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, NULL, 0, +- PAGE_SIZE); ++ PAGE_SIZE, false); + if (rc) + goto fail_mr; + +@@ -4257,7 +4258,8 @@ static struct ib_mr *__bnxt_re_user_reg_mr(struct ib_pd *ib_pd, u64 length, u64 + + umem_pgs = ib_umem_num_dma_blocks(umem, page_size); + rc = bnxt_qplib_reg_mr(&rdev->qplib_res, &mr->qplib_mr, umem, +- umem_pgs, page_size); ++ umem_pgs, page_size, ++ _is_alloc_mr_unified(rdev->dev_attr->dev_cap_flags)); + if (rc) { + ibdev_err(&rdev->ibdev, "Failed to register user MR - rc = %d\n", rc); + rc = -EIO; +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index a9afac2cbb7cf..408a34df26672 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -578,7 +578,7 @@ int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + } + + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size) ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr) + { + struct bnxt_qplib_rcfw *rcfw = res->rcfw; + struct bnxt_qplib_hwq_attr hwq_attr = {}; +@@ -640,7 +640,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + req.access = (mr->access_flags & BNXT_QPLIB_MR_ACCESS_MASK); + req.va = cpu_to_le64(mr->va); + req.key = cpu_to_le32(mr->lkey); +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) ++ if (unified_mr) + req.key = cpu_to_le32(mr->pd->id); + req.flags = cpu_to_le16(mr->flags); + req.mr_size = cpu_to_le64(mr->total_size); +@@ -651,7 +651,7 @@ int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, + if (rc) + goto fail; + +- if (_is_alloc_mr_unified(res->dattr->dev_cap_flags)) { ++ if (unified_mr) { + mr->lkey = le32_to_cpu(resp.xid); + mr->rkey = mr->lkey; + } +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.h b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +index 147b5d9c03138..5a45c55c6464c 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.h ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.h +@@ -341,7 +341,7 @@ int bnxt_qplib_alloc_mrw(struct bnxt_qplib_res *res, + int bnxt_qplib_dereg_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mrw, + bool block); + int bnxt_qplib_reg_mr(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr, +- struct ib_umem *umem, int num_pbls, u32 buf_pg_size); ++ struct ib_umem *umem, int num_pbls, u32 buf_pg_size, bool unified_mr); + int bnxt_qplib_free_mrw(struct bnxt_qplib_res *res, struct bnxt_qplib_mrw *mr); + int bnxt_qplib_alloc_fast_reg_mr(struct bnxt_qplib_res *res, + struct bnxt_qplib_mrw *mr, int max); +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-add-a-missing-kfree-of-struct-irdma_pci_f.patch b/queue-6.18/rdma-irdma-add-a-missing-kfree-of-struct-irdma_pci_f.patch new file mode 100644 index 0000000000..ad26ce7f21 --- /dev/null +++ b/queue-6.18/rdma-irdma-add-a-missing-kfree-of-struct-irdma_pci_f.patch @@ -0,0 +1,40 @@ +From fb7a59aebd04c8376c9596b73339dc37942d4d92 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:44 -0600 +Subject: RDMA/irdma: Add a missing kfree of struct irdma_pci_f for GEN2 + +From: Tatyana Nikolova + +[ Upstream commit 9e13d880ebae5da9b39ef2ed83a89737e927173f ] + +During a refactor of the irdma GEN2 code, the kfree of the irdma_pci_f struct +in icrdma_remove(), which was originally introduced upstream as part of +commit 80f2ab46c2ee ("irdma: free iwdev->rf after removing MSI-X") +was accidentally removed. + +Fixes: 0c2b80cac96e ("RDMA/irdma: Refactor GEN2 auxiliary driver") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-4-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/icrdma_if.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c b/drivers/infiniband/hw/irdma/icrdma_if.c +index 27b191f61caf4..5d3fd118e4f81 100644 +--- a/drivers/infiniband/hw/irdma/icrdma_if.c ++++ b/drivers/infiniband/hw/irdma/icrdma_if.c +@@ -320,6 +320,8 @@ static void icrdma_remove(struct auxiliary_device *aux_dev) + irdma_ib_unregister_device(iwdev); + icrdma_deinit_interrupts(iwdev->rf, cdev_info); + ++ kfree(iwdev->rf); ++ + pr_debug("INIT: Gen[%d] func[%d] device remove success\n", + rdma_ver, PCI_FUNC(cdev_info->pdev->devfn)); + } +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-add-missing-mutex-destroy.patch b/queue-6.18/rdma-irdma-add-missing-mutex-destroy.patch new file mode 100644 index 0000000000..05bb13642b --- /dev/null +++ b/queue-6.18/rdma-irdma-add-missing-mutex-destroy.patch @@ -0,0 +1,94 @@ +From 3791084bca84a177bd2a057fec8c48775944c529 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:46 -0600 +Subject: RDMA/irdma: Add missing mutex destroy + +From: Anil Samal + +[ Upstream commit 35bd787babd1f5a42641d0b1513edbed5d4e1624 ] + +Add missing destroy of ah_tbl_lock and vchnl_mutex. + +Fixes: d5edd33364a5 ("RDMA/irdma: RDMA/irdma: Add GEN3 core driver support") +Signed-off-by: Anil Samal +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-6-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/icrdma_if.c | 4 +++- + drivers/infiniband/hw/irdma/ig3rdma_if.c | 4 ++++ + drivers/infiniband/hw/irdma/verbs.c | 4 +++- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/icrdma_if.c b/drivers/infiniband/hw/irdma/icrdma_if.c +index 5d3fd118e4f81..b49fd9cf24765 100644 +--- a/drivers/infiniband/hw/irdma/icrdma_if.c ++++ b/drivers/infiniband/hw/irdma/icrdma_if.c +@@ -302,7 +302,8 @@ static int icrdma_probe(struct auxiliary_device *aux_dev, const struct auxiliary + err_ctrl_init: + icrdma_deinit_interrupts(rf, cdev_info); + err_init_interrupts: +- kfree(iwdev->rf); ++ mutex_destroy(&rf->ah_tbl_lock); ++ kfree(rf); + ib_dealloc_device(&iwdev->ibdev); + + return err; +@@ -319,6 +320,7 @@ static void icrdma_remove(struct auxiliary_device *aux_dev) + ice_rdma_update_vsi_filter(cdev_info, iwdev->vsi_num, false); + irdma_ib_unregister_device(iwdev); + icrdma_deinit_interrupts(iwdev->rf, cdev_info); ++ mutex_destroy(&iwdev->rf->ah_tbl_lock); + + kfree(iwdev->rf); + +diff --git a/drivers/infiniband/hw/irdma/ig3rdma_if.c b/drivers/infiniband/hw/irdma/ig3rdma_if.c +index 1bb42eb298ba6..e1d6670d9396e 100644 +--- a/drivers/infiniband/hw/irdma/ig3rdma_if.c ++++ b/drivers/infiniband/hw/irdma/ig3rdma_if.c +@@ -55,6 +55,7 @@ static int ig3rdma_vchnl_init(struct irdma_pci_f *rf, + ret = irdma_sc_vchnl_init(&rf->sc_dev, &virt_info); + if (ret) { + destroy_workqueue(rf->vchnl_wq); ++ mutex_destroy(&rf->sc_dev.vchnl_mutex); + return ret; + } + +@@ -124,7 +125,9 @@ static void ig3rdma_decfg_rf(struct irdma_pci_f *rf) + { + struct irdma_hw *hw = &rf->hw; + ++ mutex_destroy(&rf->ah_tbl_lock); + destroy_workqueue(rf->vchnl_wq); ++ mutex_destroy(&rf->sc_dev.vchnl_mutex); + kfree(hw->io_regs); + iounmap(hw->rdma_reg.addr); + } +@@ -149,6 +152,7 @@ static int ig3rdma_cfg_rf(struct irdma_pci_f *rf, + err = ig3rdma_cfg_regions(&rf->hw, cdev_info); + if (err) { + destroy_workqueue(rf->vchnl_wq); ++ mutex_destroy(&rf->sc_dev.vchnl_mutex); + return err; + } + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index c883c9ea5a831..c884f2ce282f9 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -5500,7 +5500,9 @@ void irdma_ib_dealloc_device(struct ib_device *ibdev) + irdma_rt_deinit_hw(iwdev); + if (!iwdev->is_vport) { + irdma_ctrl_deinit_hw(iwdev->rf); +- if (iwdev->rf->vchnl_wq) ++ if (iwdev->rf->vchnl_wq) { + destroy_workqueue(iwdev->rf->vchnl_wq); ++ mutex_destroy(&iwdev->rf->sc_dev.vchnl_mutex); ++ } + } + } +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch b/queue-6.18/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch new file mode 100644 index 0000000000..de388d432f --- /dev/null +++ b/queue-6.18/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch @@ -0,0 +1,166 @@ +From 21c2443611b58c8f804ec3c623b5d2bd9f1481f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:47 -0600 +Subject: RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY + +From: Jacob Moroni + +[ Upstream commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f ] + +The HW disables bounds checking for MRs with a length of zero, so +the driver will only allow a zero length MR if the "all_memory" +flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY +is set for the PD. + +This means that the "get_dma_mr" method will currently fail unless +the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue +because the "get_dma_mr" method is only ever invoked if the device +does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY +is set, and so far, all IRDMA HW supports the local DMA lkey. + +However, some new HW does not support the local DMA lkey, so the +"get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY +being set. + +To support HW that does not allow the local DMA lkey, the logic has +been changed to pass an explicit flag to indicate when a dma_mr is +being created so that the zero length will be allowed. + +Also, the "all_memory" flag has been forced to false for normal MR +allocation since these MRs are never supposed to provide global +unsafe rkey semantics anyway; only the MR created with "get_dma_mr" +should support this. + +Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/cm.c | 2 +- + drivers/infiniband/hw/irdma/main.h | 2 +- + drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- + drivers/infiniband/hw/irdma/verbs.h | 3 ++- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c +index c6a0a661d6e7e..f4f4f92ba63ac 100644 +--- a/drivers/infiniband/hw/irdma/cm.c ++++ b/drivers/infiniband/hw/irdma/cm.c +@@ -3710,7 +3710,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + iwpd = iwqp->iwpd; + tagged_offset = (uintptr_t)iwqp->ietf_mem.va; + ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, +- IB_ACCESS_LOCAL_WRITE, &tagged_offset); ++ IB_ACCESS_LOCAL_WRITE, &tagged_offset, false); + if (IS_ERR(ibmr)) { + ret = -ENOMEM; + goto error; +diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h +index 886b30da188ae..65ce4924dbfa6 100644 +--- a/drivers/infiniband/hw/irdma/main.h ++++ b/drivers/infiniband/hw/irdma/main.h +@@ -556,7 +556,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src); + u16 irdma_get_vlan_ipv4(u32 *addr); + void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac); + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size, +- int acc, u64 *iova_start); ++ int acc, u64 *iova_start, bool dma_mr); + int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw); + void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq); + int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index c884f2ce282f9..8c44c3fcf9731 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -3108,7 +3108,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; + info->pd_id = iwpd->sc_pd.pd_id; + info->total_len = iwmr->len; +- info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; + info->remote_access = true; + cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; + cqp_info->post_sq = 1; +@@ -3119,7 +3118,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + if (status) + return status; + +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + return 0; + } + +@@ -3263,7 +3262,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + if (iwdev->rf->sc_dev.hw_attrs.uk_attrs.feature_flags & IRDMA_FEATURE_ATOMIC_OPS) + stag_info->remote_atomics_en = (access & IB_ACCESS_REMOTE_ATOMIC) ? 1 : 0; + stag_info->pd_id = iwpd->sc_pd.pd_id; +- stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; ++ stag_info->all_memory = iwmr->dma_mr; + if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) + stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; + else +@@ -3290,7 +3289,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + + if (!ret) +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + + return ret; + } +@@ -3663,7 +3662,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr) + if (status) + return status; + +- iwmr->is_hwreg = 0; ++ iwmr->is_hwreg = false; + return 0; + } + +@@ -3786,9 +3785,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, + * @size: size of memory to register + * @access: Access rights + * @iova_start: start of virtual address for physical buffers ++ * @dma_mr: Flag indicating whether this region is a PD DMA MR + */ + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access, +- u64 *iova_start) ++ u64 *iova_start, bool dma_mr) + { + struct irdma_device *iwdev = to_iwdev(pd->device); + struct irdma_pbl *iwpbl; +@@ -3805,6 +3805,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access + iwpbl = &iwmr->iwpbl; + iwpbl->iwmr = iwmr; + iwmr->type = IRDMA_MEMREG_TYPE_MEM; ++ iwmr->dma_mr = dma_mr; + iwpbl->user_base = *iova_start; + stag = irdma_create_stag(iwdev); + if (!stag) { +@@ -3843,7 +3844,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) + { + u64 kva = 0; + +- return irdma_reg_phys_mr(pd, 0, 0, acc, &kva); ++ return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true); + } + + /** +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index ac8b387018350..aabbb3442098b 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -111,7 +111,8 @@ struct irdma_mr { + }; + struct ib_umem *region; + int access; +- u8 is_hwreg; ++ bool is_hwreg:1; ++ bool dma_mr:1; + u16 type; + u32 page_cnt; + u64 page_size; +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-do-not-set-ibk_local_dma_lkey-for-gen3.patch b/queue-6.18/rdma-irdma-do-not-set-ibk_local_dma_lkey-for-gen3.patch new file mode 100644 index 0000000000..ebb132514e --- /dev/null +++ b/queue-6.18/rdma-irdma-do-not-set-ibk_local_dma_lkey-for-gen3.patch @@ -0,0 +1,39 @@ +From 570554a36379e1910ce51e0a63e6e5174582dfdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:48 -0600 +Subject: RDMA/irdma: Do not set IBK_LOCAL_DMA_LKEY for GEN3+ + +From: Jacob Moroni + +[ Upstream commit eef3ad030b08c0f100cb18de7f604442a1adb8c7 ] + +The GEN3 hardware does not appear to support IBK_LOCAL_DMA_LKEY. Attempts +to use it will result in an AE. + +Fixes: eb31dfc2b41a ("RDMA/irdma: Restrict Memory Window and CQE Timestamping to GEN3") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-8-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/verbs.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 8c44c3fcf9731..afccd9f08b8a5 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -27,7 +27,8 @@ static int irdma_query_device(struct ib_device *ibdev, + irdma_fw_minor_ver(&rf->sc_dev); + props->device_cap_flags = IB_DEVICE_MEM_WINDOW | + IB_DEVICE_MEM_MGT_EXTENSIONS; +- props->kernel_cap_flags = IBK_LOCAL_DMA_LKEY; ++ if (hw_attrs->uk_attrs.hw_rev < IRDMA_GEN_3) ++ props->kernel_cap_flags = IBK_LOCAL_DMA_LKEY; + props->vendor_id = pcidev->vendor; + props->vendor_part_id = pcidev->device; + +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-6.18/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..173e60c41a --- /dev/null +++ b/queue-6.18/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From 52f9d32961867792b7832fcab697a0e84881b494 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index fa6325adaedec..28dfad7f940c2 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -506,12 +506,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-6.18/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..66b7745ef0 --- /dev/null +++ b/queue-6.18/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From ddab002c3046169f832326b81abf7908027fd2ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index 4ef1c29032f77..991ce4890bfb2 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3950,11 +3950,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3965,6 +3967,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-fix-sigbus-in-aeq-destroy.patch b/queue-6.18/rdma-irdma-fix-sigbus-in-aeq-destroy.patch new file mode 100644 index 0000000000..819a735ebe --- /dev/null +++ b/queue-6.18/rdma-irdma-fix-sigbus-in-aeq-destroy.patch @@ -0,0 +1,40 @@ +From 3ece0d873a2647583eaa95de6c694886b5a3624a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:45 -0600 +Subject: RDMA/irdma: Fix SIGBUS in AEQ destroy + +From: Krzysztof Czurylo + +[ Upstream commit 5eff1ecce30143c3f8924d91770d81d44bd5abe5 ] + +Removes write to IRDMA_PFINT_AEQCTL register prior to destroying AEQ, +as this register does not exist in GEN3+ hardware and this kind of IRQ +configuration is no longer required. + +Fixes: b800e82feba7 ("RDMA/irdma: Add GEN3 support for AEQ and CEQ") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-5-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index 991ce4890bfb2..cb970c9090ee0 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -4734,7 +4734,8 @@ static int irdma_sc_aeq_destroy(struct irdma_sc_aeq *aeq, u64 scratch, + u64 hdr; + + dev = aeq->dev; +- if (dev->privileged) ++ ++ if (dev->hw_attrs.uk_attrs.hw_rev <= IRDMA_GEN_2) + writel(0, dev->hw_regs[IRDMA_PFINT_AEQCTL]); + + cqp = dev->cqp; +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-fix-srq-shadow-area-address-initializatio.patch b/queue-6.18/rdma-irdma-fix-srq-shadow-area-address-initializatio.patch new file mode 100644 index 0000000000..4aaf36364c --- /dev/null +++ b/queue-6.18/rdma-irdma-fix-srq-shadow-area-address-initializatio.patch @@ -0,0 +1,38 @@ +From 326173acbdde48360c0b34a21137eb3c461809d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:50 -0600 +Subject: RDMA/irdma: Fix SRQ shadow area address initialization + +From: Jijun Wang + +[ Upstream commit 01dad9ca37c60d08f71e2ef639875ae895deede6 ] + +Fix SRQ shadow area address initialization. + +Fixes: 563e1feb5f6e ("RDMA/irdma: Add SRQ support") +Signed-off-by: Jijun Wang +Signed-off-by: Jay Bhat +Link: https://patch.msgid.link/20251125025350.180-10-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/verbs.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index afccd9f08b8a5..b8655504da290 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2307,8 +2307,8 @@ static int irdma_setup_kmode_srq(struct irdma_device *iwdev, + ukinfo->srq_size = depth >> shift; + ukinfo->shadow_area = mem->va + ring_size; + +- info->shadow_area_pa = info->srq_pa + ring_size; + info->srq_pa = mem->pa; ++ info->shadow_area_pa = info->srq_pa + ring_size; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.18/rdma-irdma-remove-doorbell-elision-logic.patch b/queue-6.18/rdma-irdma-remove-doorbell-elision-logic.patch new file mode 100644 index 0000000000..14b801d944 --- /dev/null +++ b/queue-6.18/rdma-irdma-remove-doorbell-elision-logic.patch @@ -0,0 +1,109 @@ +From d568ca2803ec1f229d878fd173bc8e641758c15a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:49 -0600 +Subject: RDMA/irdma: Remove doorbell elision logic + +From: Jacob Moroni + +[ Upstream commit 62356fccb195f83d2ceafc787c5ba87ebbe5edfe ] + +In some cases, this logic can result in doorbell writes being +skipped when they should not have been (at least on GEN3 HW), +so remove it. This also means that the mb() can be safely +downgraded to dma_wmb(). + +Fixes: 551c46edc769 ("RDMA/irdma: Add user/kernel shared libraries") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-9-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/puda.c | 1 - + drivers/infiniband/hw/irdma/uk.c | 31 ++---------------------------- + drivers/infiniband/hw/irdma/user.h | 1 - + 3 files changed, 2 insertions(+), 31 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/puda.c b/drivers/infiniband/hw/irdma/puda.c +index 694e5a9ed15d0..9cd14a50f1a93 100644 +--- a/drivers/infiniband/hw/irdma/puda.c ++++ b/drivers/infiniband/hw/irdma/puda.c +@@ -685,7 +685,6 @@ static int irdma_puda_qp_create(struct irdma_puda_rsrc *rsrc) + ukqp->rq_size = rsrc->rq_size; + + IRDMA_RING_INIT(ukqp->sq_ring, ukqp->sq_size); +- IRDMA_RING_INIT(ukqp->initial_ring, ukqp->sq_size); + IRDMA_RING_INIT(ukqp->rq_ring, ukqp->rq_size); + ukqp->wqe_alloc_db = qp->pd->dev->wqe_alloc_db; + +diff --git a/drivers/infiniband/hw/irdma/uk.c b/drivers/infiniband/hw/irdma/uk.c +index ce1ae10c30fca..d5568584ad5e3 100644 +--- a/drivers/infiniband/hw/irdma/uk.c ++++ b/drivers/infiniband/hw/irdma/uk.c +@@ -114,33 +114,8 @@ void irdma_clr_wqes(struct irdma_qp_uk *qp, u32 qp_wqe_idx) + */ + void irdma_uk_qp_post_wr(struct irdma_qp_uk *qp) + { +- u64 temp; +- u32 hw_sq_tail; +- u32 sw_sq_head; +- +- /* valid bit is written and loads completed before reading shadow */ +- mb(); +- +- /* read the doorbell shadow area */ +- get_64bit_val(qp->shadow_area, 0, &temp); +- +- hw_sq_tail = (u32)FIELD_GET(IRDMA_QP_DBSA_HW_SQ_TAIL, temp); +- sw_sq_head = IRDMA_RING_CURRENT_HEAD(qp->sq_ring); +- if (sw_sq_head != qp->initial_ring.head) { +- if (sw_sq_head != hw_sq_tail) { +- if (sw_sq_head > qp->initial_ring.head) { +- if (hw_sq_tail >= qp->initial_ring.head && +- hw_sq_tail < sw_sq_head) +- writel(qp->qp_id, qp->wqe_alloc_db); +- } else { +- if (hw_sq_tail >= qp->initial_ring.head || +- hw_sq_tail < sw_sq_head) +- writel(qp->qp_id, qp->wqe_alloc_db); +- } +- } +- } +- +- qp->initial_ring.head = qp->sq_ring.head; ++ dma_wmb(); ++ writel(qp->qp_id, qp->wqe_alloc_db); + } + + /** +@@ -1574,7 +1549,6 @@ static void irdma_setup_connection_wqes(struct irdma_qp_uk *qp, + qp->conn_wqes = move_cnt; + IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->sq_ring, move_cnt); + IRDMA_RING_MOVE_TAIL_BY_COUNT(qp->sq_ring, move_cnt); +- IRDMA_RING_MOVE_HEAD_BY_COUNT_NOCHECK(qp->initial_ring, move_cnt); + } + + /** +@@ -1719,7 +1693,6 @@ int irdma_uk_qp_init(struct irdma_qp_uk *qp, struct irdma_qp_uk_init_info *info) + qp->max_sq_frag_cnt = info->max_sq_frag_cnt; + sq_ring_size = qp->sq_size << info->sq_shift; + IRDMA_RING_INIT(qp->sq_ring, sq_ring_size); +- IRDMA_RING_INIT(qp->initial_ring, sq_ring_size); + if (info->first_sq_wq) { + irdma_setup_connection_wqes(qp, info); + qp->swqe_polarity = 1; +diff --git a/drivers/infiniband/hw/irdma/user.h b/drivers/infiniband/hw/irdma/user.h +index ab57f689827a0..aeebf768174ab 100644 +--- a/drivers/infiniband/hw/irdma/user.h ++++ b/drivers/infiniband/hw/irdma/user.h +@@ -456,7 +456,6 @@ struct irdma_srq_uk { + struct irdma_uk_attrs *uk_attrs; + __le64 *shadow_area; + struct irdma_ring srq_ring; +- struct irdma_ring initial_ring; + u32 srq_id; + u32 srq_size; + u32 max_srq_frag_cnt; +-- +2.51.0 + diff --git a/queue-6.18/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-6.18/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..6efaec2448 --- /dev/null +++ b/queue-6.18/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From a0291d98b3f4625d23abbad98202f77dd14a4d9a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index ef4abdea3c2d2..9ecc6343455d6 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1450,7 +1450,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-6.18/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch b/queue-6.18/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch new file mode 100644 index 0000000000..965855eb3a --- /dev/null +++ b/queue-6.18/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch @@ -0,0 +1,94 @@ +From 29e15fb9bfd97da274375e740741ae97e57e7454 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:52:03 -0700 +Subject: RDMA/rxe: Fix null deref on srq->rq.queue after resize failure + +From: Zhu Yanjun + +[ Upstream commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 ] + +A NULL pointer dereference can occur in rxe_srq_chk_attr() when +ibv_modify_srq() is invoked twice in succession under certain error +conditions. The first call may fail in rxe_queue_resize(), which leads +rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then +triggers a crash (null deref) when accessing +srq->rq.queue->buf->index_mask. + +Call Trace: + +rxe_modify_srq+0x170/0x480 [rdma_rxe] +? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe] +? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs] +? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs] +ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs] +? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs] +? tryinc_node_nr_active+0xe6/0x150 +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs] +? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs] +? __pfx___raw_spin_lock_irqsave+0x10/0x10 +? __pfx_do_vfs_ioctl+0x10/0x10 +? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0 +? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10 +ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs] +? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs] +__x64_sys_ioctl+0x138/0x1c0 +do_syscall_64+0x82/0x250 +? fdget_pos+0x58/0x4c0 +? ksys_write+0xf3/0x1c0 +? __pfx_ksys_write+0x10/0x10 +? do_syscall_64+0xc8/0x250 +? __pfx_vm_mmap_pgoff+0x10/0x10 +? fget+0x173/0x230 +? fput+0x2a/0x80 +? ksys_mmap_pgoff+0x224/0x4c0 +? do_syscall_64+0xc8/0x250 +? do_user_addr_fault+0x37b/0xfe0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Tested-by: Liu Yi +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c +index 3661cb627d28a..2a234f26ac104 100644 +--- a/drivers/infiniband/sw/rxe/rxe_srq.c ++++ b/drivers/infiniband/sw/rxe/rxe_srq.c +@@ -171,7 +171,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + udata, mi, &srq->rq.producer_lock, + &srq->rq.consumer_lock); + if (err) +- goto err_free; ++ return err; + + srq->rq.max_wr = attr->max_wr; + } +@@ -180,11 +180,6 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + srq->limit = attr->srq_limit; + + return 0; +- +-err_free: +- rxe_queue_cleanup(q); +- srq->rq.queue = NULL; +- return err; + } + + void rxe_srq_cleanup(struct rxe_pool_elem *elem) +-- +2.51.0 + diff --git a/queue-6.18/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-6.18/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..119b2981c6 --- /dev/null +++ b/queue-6.18/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From 98319a74d2c3f19d519a3fc3184c31479bfee28d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index dd7b10e768c06..fc93612f4ec0c 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1618,6 +1618,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1637,11 +1639,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-6.18/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..ffd7046520 --- /dev/null +++ b/queue-6.18/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 45fcc2f91cd74bb03d3e18427958633fd1a3684d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index fc93612f4ec0c..b38b087eccfd7 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1947,6 +1947,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1955,6 +1956,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2497,22 +2499,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2532,11 +2538,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-6.18/regulator-pca9450-fix-error-code-in-probe.patch b/queue-6.18/regulator-pca9450-fix-error-code-in-probe.patch new file mode 100644 index 0000000000..c71083487d --- /dev/null +++ b/queue-6.18/regulator-pca9450-fix-error-code-in-probe.patch @@ -0,0 +1,42 @@ +From cf0d6ae8cb2d34c5f590aaa932dbe5c8d6ab540f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 16:35:24 +0300 +Subject: regulator: pca9450: Fix error code in probe() + +From: Dan Carpenter + +[ Upstream commit 670500b41e543c5cb09eb9f7f0e4e26c5b5fdf7e ] + +Return "PTR_ERR(pca9450->sd_vsel_gpio)" instead of "ret". The "ret" +variable is success at this point. + +Fixes: 3ce6f4f943dd ("regulator: pca9450: Fix control register for LDO5") +Signed-off-by: Dan Carpenter +Link: https://patch.msgid.link/aSBqnPoBrsNB1Ale@stanley.mountain +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/pca9450-regulator.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c +index 4be270f4d6c35..91b96dbab328b 100644 +--- a/drivers/regulator/pca9450-regulator.c ++++ b/drivers/regulator/pca9450-regulator.c +@@ -1251,10 +1251,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) + * to this signal (if SION bit is set in IOMUX). + */ + pca9450->sd_vsel_gpio = gpiod_get_optional(&ldo5->dev, "sd-vsel", GPIOD_IN); +- if (IS_ERR(pca9450->sd_vsel_gpio)) { +- dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n"); +- return ret; +- } ++ if (IS_ERR(pca9450->sd_vsel_gpio)) ++ return dev_err_probe(&i2c->dev, PTR_ERR(pca9450->sd_vsel_gpio), ++ "Failed to get SD_VSEL GPIO\n"); + + pca9450->sd_vsel_fixed_low = + of_property_read_bool(ldo5->dev.of_node, "nxp,sd-vsel-fixed-low"); +-- +2.51.0 + diff --git a/queue-6.18/reinstate-resource-avoid-unnecessary-lookups-in-find.patch b/queue-6.18/reinstate-resource-avoid-unnecessary-lookups-in-find.patch new file mode 100644 index 0000000000..e695e93d8a --- /dev/null +++ b/queue-6.18/reinstate-resource-avoid-unnecessary-lookups-in-find.patch @@ -0,0 +1,85 @@ +From 20bf22a869fde4c9a1ce5edb540918c6e6992fab Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:53:49 +0000 +Subject: Reinstate "resource: avoid unnecessary lookups in + find_next_iomem_res()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilias Stamatis + +[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ] + +Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only +logic") removed an optimization introduced by commit 756398750e11 +("resource: avoid unnecessary lookups in find_next_iomem_res()"). That +was not called out in the message of the first commit explicitly so it's +not entirely clear whether removing the optimization happened +inadvertently or not. + +As the original commit message of the optimization explains there is no +point considering the children of a subtree in find_next_iomem_res() if +the top level range does not match. + +Reinstating the optimization results in performance improvements in +systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem +in such platforms takes 700-1500μs without the optimisation and 10-50μs +with the optimisation. + +Note that even though commit 97523a4edb7b removed the 'sibling_only' +parameter from next_resource(), newer kernels have basically reinstated it +under the name 'skip_children'. + +Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u +Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") +Signed-off-by: Ilias Stamatis +Acked-by: David Hildenbrand (Red Hat) +Cc: Andriy Shevchenko +Cc: Baoquan He +Cc: "Huang, Ying" +Cc: Nadav Amit +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index b9fa2a4ce089c..e4e9bac12e6e1 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -341,6 +341,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + unsigned long flags, unsigned long desc, + struct resource *res) + { ++ /* Skip children until we find a top level range that matches */ ++ bool skip_children = true; + struct resource *p; + + if (!res) +@@ -351,7 +353,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for_each_resource(&iomem_resource, p, false) { ++ for_each_resource(&iomem_resource, p, skip_children) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -362,6 +364,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + ++ /* ++ * We found a top level range that matches what we are looking ++ * for. Time to start checking children too. ++ */ ++ skip_children = false; ++ + /* Found a match, break */ + if (is_type_match(p, flags, desc)) + break; +-- +2.51.0 + diff --git a/queue-6.18/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch b/queue-6.18/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch new file mode 100644 index 0000000000..905dde24ac --- /dev/null +++ b/queue-6.18/remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch @@ -0,0 +1,67 @@ +From 87ef0c973df87ebbe18de2f2946819168ed38cfc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 20:33:15 +0800 +Subject: remoteproc: imx_rproc: Fix runtime PM cleanup and improve remove path + +From: Peng Fan + +[ Upstream commit 80405a34e1f8975cdb2d7d8679bca7f768861035 ] + +Proper cleanup should be done when rproc_add() fails by invoking both +pm_runtime_disable() and pm_runtime_put_noidle() to avoid leaving the +device in an inconsistent power state. + +Fix it by adding pm_runtime_put_noidle() and pm_runtime_disable() +in the error path. + +Also Update the remove() callback to use pm_runtime_put_noidle() instead of +pm_runtime_put(), to clearly indicate that only need to restore the usage +count. + +Fixes: a876a3aacc43 ("remoteproc: imx_rproc: detect and attach to pre-booted remote cores") +Cc: Ulf Hansson +Cc: Hiago De Franco +Suggested-by: Ulf Hansson +Signed-off-by: Peng Fan +Reviewed-by: Ulf Hansson +Link: https://lore.kernel.org/r/20250926-imx_rproc_v3-v3-1-4c0ec279cc5f@nxp.com +Signed-off-by: Mathieu Poirier +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/imx_rproc.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c +index bb25221a4a898..8424e6ea5569b 100644 +--- a/drivers/remoteproc/imx_rproc.c ++++ b/drivers/remoteproc/imx_rproc.c +@@ -1136,11 +1136,16 @@ static int imx_rproc_probe(struct platform_device *pdev) + ret = rproc_add(rproc); + if (ret) { + dev_err(dev, "rproc_add failed\n"); +- goto err_put_clk; ++ goto err_put_pm; + } + + return 0; + ++err_put_pm: ++ if (dcfg->method == IMX_RPROC_SCU_API) { ++ pm_runtime_disable(dev); ++ pm_runtime_put_noidle(dev); ++ } + err_put_clk: + clk_disable_unprepare(priv->clk); + err_put_scu: +@@ -1160,7 +1165,7 @@ static void imx_rproc_remove(struct platform_device *pdev) + + if (priv->dcfg->method == IMX_RPROC_SCU_API) { + pm_runtime_disable(priv->dev); +- pm_runtime_put(priv->dev); ++ pm_runtime_put_noidle(priv->dev); + } + clk_disable_unprepare(priv->clk); + rproc_del(rproc); +-- +2.51.0 + diff --git a/queue-6.18/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-6.18/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..06c9d8c78d --- /dev/null +++ b/queue-6.18/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From 8bd2029f0ac816c412392f9454fb5b36ff4b5c46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index 07c88623f5978..23ec87827d4f8 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -864,9 +864,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.18/revert-mtd-rawnand-marvell-fix-layouts.patch b/queue-6.18/revert-mtd-rawnand-marvell-fix-layouts.patch new file mode 100644 index 0000000000..2cb94fed50 --- /dev/null +++ b/queue-6.18/revert-mtd-rawnand-marvell-fix-layouts.patch @@ -0,0 +1,51 @@ +From 3b5d103368d5fd3e1e9e7168105ad6e299bc699b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:41 +1300 +Subject: Revert "mtd: rawnand: marvell: fix layouts" + +From: Aryan Srivastava + +[ Upstream commit fbd72cb463fdea3a0c900dd5d6e813cdebc3a73c ] + +This reverts commit e6a30d0c48a1e8a68f1cc413bee65302ab03ddfb. + +This change resulted in the 8bit ECC layouts having the incorrect amount +of read/write chunks, the last spare bytes chunk would always be missed. + +Fixes: e6a30d0c48a1 ("mtd: rawnand: marvell: fix layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 303b3016a070b..38b7eb5b992c8 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -290,13 +290,16 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { + MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,64, 30), +- MARVELL_LAYOUT( 2048, 512, 16, 4, 4, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 2048, 512, 12, 3, 2, 704, 0, 30,640, 0, 30), ++ MARVELL_LAYOUT( 2048, 512, 16, 5, 4, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), +- MARVELL_LAYOUT( 4096, 512, 8, 4, 4, 1024, 0, 30, 0, 64, 30), +- MARVELL_LAYOUT( 4096, 512, 16, 8, 8, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), ++ MARVELL_LAYOUT( 4096, 512, 12, 6, 5, 704, 0, 30,576, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 16, 9, 8, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 8192, 512, 4, 4, 4, 2048, 0, 30, 0, 0, 0), +- MARVELL_LAYOUT( 8192, 512, 8, 8, 8, 1024, 0, 30, 0, 160, 30), +- MARVELL_LAYOUT( 8192, 512, 16, 16, 16, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 8192, 512, 8, 9, 8, 1024, 0, 30, 0, 160, 30), ++ MARVELL_LAYOUT( 8192, 512, 12, 12, 11, 704, 0, 30,448, 64, 30), ++ MARVELL_LAYOUT( 8192, 512, 16, 17, 16, 512, 0, 30, 0, 32, 30), + }; + + /** +-- +2.51.0 + diff --git a/queue-6.18/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch b/queue-6.18/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch new file mode 100644 index 0000000000..8889613af3 --- /dev/null +++ b/queue-6.18/revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch @@ -0,0 +1,46 @@ +From 0cb1998b87935146d30639426367661b395957c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:18:39 +0300 +Subject: Revert "wifi: mt76: mt792x: improve monitor interface handling" + +From: Fedor Pchelkin + +[ Upstream commit cdb2941a516cf06929293604e2e0f4c1d6f3541e ] + +This reverts commit 55e95ce469d0c61041bae48b2ebb7fcbf6d1ba7f. + +mt792x drivers don't seem to support multi-radio devices yet. At least +they don't mess with `struct wiphy_radio` at the moment. + +Packet capturing on monitor interface doesn't work after the blamed patch: + + tcpdump -i wls6mon -n -vvv + +Revert the NO_VIRTUAL_MONITOR feature for now to resolve the issue. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 55e95ce469d0 ("wifi: mt76: mt792x: improve monitor interface handling") +Signed-off-by: Fedor Pchelkin +Link: https://patch.msgid.link/20251027111843.38975-1-pchelkin@ispras.ru +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt792x_core.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +index c0e56541a9547..9cad572c34a38 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c ++++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c +@@ -688,7 +688,6 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) + ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS); + ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW); + ieee80211_hw_set(hw, CONNECTION_MONITOR); +- ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR); + ieee80211_hw_set(hw, SUPPORTS_MULTI_BSSID); + ieee80211_hw_set(hw, SUPPORTS_ONLY_HE_MULTI_BSSID); + +-- +2.51.0 + diff --git a/queue-6.18/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch b/queue-6.18/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch new file mode 100644 index 0000000000..843c45d6f4 --- /dev/null +++ b/queue-6.18/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch @@ -0,0 +1,84 @@ +From ee40fdec7832d4ba3b22aa7ca60ae38095e02d22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 21:35:43 +0800 +Subject: RISC-V: KVM: Fix guest page fault within HLV* instructions + +From: Fangyu Yu + +[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ] + +When executing HLV* instructions at the HS mode, a guest page fault +may occur when a g-stage page table migration between triggering the +virtual instruction exception and executing the HLV* instruction. + +This may be a corner case, and one simpler way to handle this is to +re-execute the instruction where the virtual instruction exception +occurred, and the guest page fault will be automatically handled. + +Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") +Signed-off-by: Fangyu Yu +Reviewed-by: Anup Patel +Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index de1f96ea62251..4d89b94128aea 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -298,6 +298,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + return (rc <= 0) ? rc : 1; + } + ++static bool is_load_guest_page_fault(unsigned long scause) ++{ ++ /** ++ * If a g-stage page fault occurs, the direct approach ++ * is to let the g-stage page fault handler handle it ++ * naturally, however, calling the g-stage page fault ++ * handler here seems rather strange. ++ * Considering this is a corner case, we can directly ++ * return to the guest and re-execute the same PC, this ++ * will trigger a g-stage page fault again and then the ++ * regular g-stage page fault handler will populate ++ * g-stage page table. ++ */ ++ return (scause == EXC_LOAD_GUEST_PAGE_FAULT); ++} ++ + /** + * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap + * +@@ -323,6 +339,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + return 1; +@@ -378,6 +396,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +@@ -504,6 +524,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +-- +2.51.0 + diff --git a/queue-6.18/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch b/queue-6.18/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch new file mode 100644 index 0000000000..c91e5d093d --- /dev/null +++ b/queue-6.18/rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch @@ -0,0 +1,229 @@ +From fe25ed5dab350ce5a683f39876cde11c248e27fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 23:27:57 +0000 +Subject: rqspinlock: Enclose lock/unlock within lock entry acquisitions + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit beb7021a6003d9c6a463fffca0d6311efb8e0e66 ] + +Ritesh reported that timeouts occurred frequently for rqspinlock despite +reentrancy on the same lock on the same CPU in [0]. This patch closes +one of the races leading to this behavior, and reduces the frequency of +timeouts. + +We currently have a tiny window between the fast-path cmpxchg and the +grabbing of the lock entry where an NMI could land, attempt the same +lock that was just acquired, and end up timing out. This is not ideal. +Instead, move the lock entry acquisition from the fast path to before +the cmpxchg, and remove the grabbing of the lock entry in the slow path, +assuming it was already taken by the fast path. The TAS fallback is +invoked directly without being preceded by the typical fast path, +therefore we must continue to grab the deadlock detection entry in that +case. + +Case on lock leading to missed AA: + +cmpxchg lock A + +... rqspinlock acquisition of A +... timeout + +grab_held_lock_entry(A) + +There is a similar case when unlocking the lock. If the NMI lands +between the WRITE_ONCE and smp_store_release, it is possible that we end +up in a situation where the NMI fails to diagnose the AA condition, +leading to a timeout. + +Case on unlock leading to missed AA: + +WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) + +... rqspinlock acquisition of A +... timeout + +smp_store_release(A->locked, 0) + +The patch changes the order on unlock to smp_store_release() succeeded +by WRITE_ONCE() of NULL. This avoids the missed AA detection described +above, but may lead to a false positive if the NMI lands between these +two statements, which is acceptable (and preferred over a timeout). + +The original intention of the reverse order on unlock was to prevent the +following possible misdiagnosis of an ABBA scenario: + +grab entry A +lock A +grab entry B +lock B +unlock B + smp_store_release(B->locked, 0) + grab entry B + lock B + grab entry A + lock A + ! + WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) + +If the store release were is after the WRITE_ONCE, the other CPU would +not observe B in the table of the CPU unlocking the lock B. However, +since the threads are obviously participating in an ABBA deadlock, it +is no longer appealing to use the order above since it may lead to a +250 ms timeout due to missed AA detection. + + [0]: https://lore.kernel.org/bpf/CAH6OuBTjG+N=+GGwcpOUbeDN563oz4iVcU3rbse68egp9wj9_A@mail.gmail.com + +Fixes: 0d80e7f951be ("rqspinlock: Choose trylock fallback for NMI waiters") +Reported-by: Ritesh Oedayrajsingh Varma +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251128232802.1031906-2-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/asm-generic/rqspinlock.h | 60 +++++++++++++++++--------------- + kernel/bpf/rqspinlock.c | 15 ++++---- + 2 files changed, 38 insertions(+), 37 deletions(-) + +diff --git a/include/asm-generic/rqspinlock.h b/include/asm-generic/rqspinlock.h +index 6d4244d643df3..0f2dcbbfee2f0 100644 +--- a/include/asm-generic/rqspinlock.h ++++ b/include/asm-generic/rqspinlock.h +@@ -129,8 +129,8 @@ static __always_inline void release_held_lock_entry(void) + * for lock B + * release_held_lock_entry + * +- * try_cmpxchg_acquire for lock A + * grab_held_lock_entry ++ * try_cmpxchg_acquire for lock A + * + * Lack of any ordering means reordering may occur such that dec, inc + * are done before entry is overwritten. This permits a remote lock +@@ -139,13 +139,8 @@ static __always_inline void release_held_lock_entry(void) + * CPU holds a lock it is attempting to acquire, leading to false ABBA + * diagnosis). + * +- * In case of unlock, we will always do a release on the lock word after +- * releasing the entry, ensuring that other CPUs cannot hold the lock +- * (and make conclusions about deadlocks) until the entry has been +- * cleared on the local CPU, preventing any anomalies. Reordering is +- * still possible there, but a remote CPU cannot observe a lock in our +- * table which it is already holding, since visibility entails our +- * release store for the said lock has not retired. ++ * The case of unlock is treated differently due to NMI reentrancy, see ++ * comments in res_spin_unlock. + * + * In theory we don't have a problem if the dec and WRITE_ONCE above get + * reordered with each other, we either notice an empty NULL entry on +@@ -175,10 +170,22 @@ static __always_inline int res_spin_lock(rqspinlock_t *lock) + { + int val = 0; + +- if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL))) { +- grab_held_lock_entry(lock); ++ /* ++ * Grab the deadlock detection entry before doing the cmpxchg, so that ++ * reentrancy due to NMIs between the succeeding cmpxchg and creation of ++ * held lock entry can correctly detect an acquisition attempt in the ++ * interrupted context. ++ * ++ * cmpxchg lock A ++ * ++ * res_spin_lock(A) --> missed AA, leads to timeout ++ * ++ * grab_held_lock_entry(A) ++ */ ++ grab_held_lock_entry(lock); ++ ++ if (likely(atomic_try_cmpxchg_acquire(&lock->val, &val, _Q_LOCKED_VAL))) + return 0; +- } + return resilient_queued_spin_lock_slowpath(lock, val); + } + +@@ -192,28 +199,25 @@ static __always_inline void res_spin_unlock(rqspinlock_t *lock) + { + struct rqspinlock_held *rqh = this_cpu_ptr(&rqspinlock_held_locks); + +- if (unlikely(rqh->cnt > RES_NR_HELD)) +- goto unlock; +- WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL); +-unlock: + /* +- * Release barrier, ensures correct ordering. See release_held_lock_entry +- * for details. Perform release store instead of queued_spin_unlock, +- * since we use this function for test-and-set fallback as well. When we +- * have CONFIG_QUEUED_SPINLOCKS=n, we clear the full 4-byte lockword. ++ * Release barrier, ensures correct ordering. Perform release store ++ * instead of queued_spin_unlock, since we use this function for the TAS ++ * fallback as well. When we have CONFIG_QUEUED_SPINLOCKS=n, we clear ++ * the full 4-byte lockword. + * +- * Like release_held_lock_entry, we can do the release before the dec. +- * We simply care about not seeing the 'lock' in our table from a remote +- * CPU once the lock has been released, which doesn't rely on the dec. ++ * Perform the smp_store_release before clearing the lock entry so that ++ * NMIs landing in the unlock path can correctly detect AA issues. The ++ * opposite order shown below may lead to missed AA checks: + * +- * Unlike smp_wmb(), release is not a two way fence, hence it is +- * possible for a inc to move up and reorder with our clearing of the +- * entry. This isn't a problem however, as for a misdiagnosis of ABBA, +- * the remote CPU needs to hold this lock, which won't be released until +- * the store below is done, which would ensure the entry is overwritten +- * to NULL, etc. ++ * WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL) ++ * ++ * res_spin_lock(A) --> missed AA, leads to timeout ++ * ++ * smp_store_release(A->locked, 0) + */ + smp_store_release(&lock->locked, 0); ++ if (likely(rqh->cnt <= RES_NR_HELD)) ++ WRITE_ONCE(rqh->locks[rqh->cnt - 1], NULL); + this_cpu_dec(rqspinlock_held_locks.cnt); + } + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index 21be48108e962..f4c534fa4e87b 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -275,6 +275,10 @@ int __lockfunc resilient_tas_spin_lock(rqspinlock_t *lock) + int val, ret = 0; + + RES_INIT_TIMEOUT(ts); ++ /* ++ * The fast path is not invoked for the TAS fallback, so we must grab ++ * the deadlock detection entry here. ++ */ + grab_held_lock_entry(lock); + + /* +@@ -397,10 +401,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + goto queue; + } + +- /* +- * Grab an entry in the held locks array, to enable deadlock detection. +- */ +- grab_held_lock_entry(lock); ++ /* Deadlock detection entry already held after failing fast path. */ + + /* + * We're pending, wait for the owner to go away. +@@ -448,11 +449,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + */ + queue: + lockevent_inc(lock_slowpath); +- /* +- * Grab deadlock detection entry for the queue path. +- */ +- grab_held_lock_entry(lock); +- ++ /* Deadlock detection entry already held after failing fast path. */ + node = this_cpu_ptr(&rqnodes[0].mcs); + idx = node->count++; + tail = encode_tail(smp_processor_id(), idx); +-- +2.51.0 + diff --git a/queue-6.18/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch b/queue-6.18/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch new file mode 100644 index 0000000000..9664d21e67 --- /dev/null +++ b/queue-6.18/rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch @@ -0,0 +1,87 @@ +From 483ac8ec222ea40f149bb70ac3d8b76feb4d5f32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 23:27:59 +0000 +Subject: rqspinlock: Use trylock fallback when per-CPU rqnode is busy + +From: Kumar Kartikeya Dwivedi + +[ Upstream commit 81d5a6a438595e46be191d602e5c2d6d73992fdc ] + +In addition to deferring to the trylock fallback in NMIs, only do so +when an rqspinlock waiter is queued on the current CPU. This is detected +by noticing a non-zero node index. This allows NMI waiters to join the +waiter queue if it isn't interrupting an existing rqspinlock waiter, and +increase the chances of fairly obtaining the lock, performing deadlock +detection as the head, and not being starved while attempting the +trylock. + +The trylock path in particular is unlikely to succeed under contention, +as it relies on the lock word becoming 0, which indicates no contention. +This means that the most likely result for NMIs attempting a trylock is +a timeout under contention if they don't hit an AA or ABBA case. + +The core problem being addressed through the fixed commit was removing +the dependency edge between an NMI queue waiter and the queue waiter it +is interrupting. Whenever a circular dependency forms, and with no way +to break it (as non-head waiters don't poll for deadlocks or timeouts), +we would enter into a deadlock. A trylock either breaks such an edge by +probing for deadlocks, and finally terminating the waiting loop using a +timeout. + +By excluding queueing on CPUs where the node index is non-zero for NMIs, +this sort of dependency is broken. The CPU enters the trylock path for +those cases, and falls back to deadlock checks and timeouts. However, in +other case where it doesn't interrupt the CPU in the slow path while its +queued on the lock, it can join the queue as a normal waiter, and avoid +trylock associated starvation and subsequent timeouts. + +There are a few remaining cases here that matter: the NMI can still +preempt the owner in its critical section, and if it queues as a +non-head waiter, it can end up impeding the progress of the owner. While +this won't deadlock, since the head waiter will eventually signal the +NMI waiter to either stop (due to a timeout), it can still lead to long +timeouts. These gaps will be addressed in subsequent commits. + +Note that while the node count detection approach is less conservative +than simply deferring NMIs to trylock, it is going to return errors +where attempts to lock B in NMI happen while waiters for lock A are in a +lower context on the same CPU. However, this only occurs when the lower +context is queued in the slow path, and the NMI attempt can proceed +without failure in all other cases. To continue to prevent AA deadlocks +(or ABBA in a similar NMI interrupting lower context pattern), we'd need +a more fleshed out algorithm to unlink NMI waiters after they queue and +detect such cases. However, all that complexity isn't appealing yet to +reduce the failure rate in the small window inside the slow path. + +It is important to note that reentrancy in the slow path can also happen +through trace_contention_{begin,end}, but in those cases, unlike an NMI, +the forward progress of the head waiter (or the predecessor in general) +is not being blocked. + +Fixes: 0d80e7f951be ("rqspinlock: Choose trylock fallback for NMI waiters") +Reported-by: Ritesh Oedayrajsingh Varma +Suggested-by: Alexei Starovoitov +Signed-off-by: Kumar Kartikeya Dwivedi +Link: https://lore.kernel.org/r/20251128232802.1031906-4-memxor@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/rqspinlock.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/bpf/rqspinlock.c b/kernel/bpf/rqspinlock.c +index f4c534fa4e87b..3faf9cbd6c753 100644 +--- a/kernel/bpf/rqspinlock.c ++++ b/kernel/bpf/rqspinlock.c +@@ -465,7 +465,7 @@ int __lockfunc resilient_queued_spin_lock_slowpath(rqspinlock_t *lock, u32 val) + * any MCS node. This is not the most elegant solution, but is + * simple enough. + */ +- if (unlikely(idx >= _Q_MAX_NODES || in_nmi())) { ++ if (unlikely(idx >= _Q_MAX_NODES || (in_nmi() && idx > 0))) { + lockevent_inc(lock_no_node); + RES_RESET_TIMEOUT(ts, RES_DEF_TIMEOUT); + while (!queued_spin_trylock(lock)) { +-- +2.51.0 + diff --git a/queue-6.18/rtla-fix-a-overriding-t-argument.patch b/queue-6.18/rtla-fix-a-overriding-t-argument.patch new file mode 100644 index 0000000000..750bc15521 --- /dev/null +++ b/queue-6.18/rtla-fix-a-overriding-t-argument.patch @@ -0,0 +1,92 @@ +From efc97d905ef4b17bfae001c0ccf87422125ebae4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 11:19:08 -0500 +Subject: rtla: Fix -a overriding -t argument + +From: Ivan Pravdin + +[ Upstream commit ddb6e42494e5c48c17e64f29b7674b9add486a19 ] + +When running rtla as + + `rtla -t custom_file.txt -a 100` + +-a options override trace output filename specified by -t option. +Running the command above will create _trace.txt file +instead of custom_file.txt. Fix this by making sure that -a option does +not override trace output filename even if it's passed after trace +output filename is specified. + +Fixes: 173a3b014827 ("rtla/timerlat: Add the automatic trace option") +Signed-off-by: Ivan Pravdin +Reviewed-by: Tomas Glozar +Link: https://lore.kernel.org/r/b6ae60424050b2c1c8709e18759adead6012b971.1762186418.git.ipravdin.official@gmail.com +[ use capital letter in subject, as required by tracing subsystem ] +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/src/osnoise_hist.c | 3 ++- + tools/tracing/rtla/src/osnoise_top.c | 3 ++- + tools/tracing/rtla/src/timerlat_hist.c | 3 ++- + tools/tracing/rtla/src/timerlat_top.c | 3 ++- + 4 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/tools/tracing/rtla/src/osnoise_hist.c b/tools/tracing/rtla/src/osnoise_hist.c +index dffb6d0a98d7d..d22feb4d6cc9d 100644 +--- a/tools/tracing/rtla/src/osnoise_hist.c ++++ b/tools/tracing/rtla/src/osnoise_hist.c +@@ -557,7 +557,8 @@ static struct common_params + params->threshold = 1; + + /* set trace */ +- trace_output = "osnoise_trace.txt"; ++ if (!trace_output) ++ trace_output = "osnoise_trace.txt"; + + break; + case 'b': +diff --git a/tools/tracing/rtla/src/osnoise_top.c b/tools/tracing/rtla/src/osnoise_top.c +index 95418f7ecc961..a8d31030c4122 100644 +--- a/tools/tracing/rtla/src/osnoise_top.c ++++ b/tools/tracing/rtla/src/osnoise_top.c +@@ -397,7 +397,8 @@ struct common_params *osnoise_top_parse_args(int argc, char **argv) + params->threshold = 1; + + /* set trace */ +- trace_output = "osnoise_trace.txt"; ++ if (!trace_output) ++ trace_output = "osnoise_trace.txt"; + + break; + case 'c': +diff --git a/tools/tracing/rtla/src/timerlat_hist.c b/tools/tracing/rtla/src/timerlat_hist.c +index 606c1688057b2..3d56df3d5fa0d 100644 +--- a/tools/tracing/rtla/src/timerlat_hist.c ++++ b/tools/tracing/rtla/src/timerlat_hist.c +@@ -878,7 +878,8 @@ static struct common_params + params->print_stack = auto_thresh; + + /* set trace */ +- trace_output = "timerlat_trace.txt"; ++ if (!trace_output) ++ trace_output = "timerlat_trace.txt"; + + break; + case 'c': +diff --git a/tools/tracing/rtla/src/timerlat_top.c b/tools/tracing/rtla/src/timerlat_top.c +index fc479a0dcb597..6cc9a3607c665 100644 +--- a/tools/tracing/rtla/src/timerlat_top.c ++++ b/tools/tracing/rtla/src/timerlat_top.c +@@ -628,7 +628,8 @@ static struct common_params + params->print_stack = auto_thresh; + + /* set trace */ +- trace_output = "timerlat_trace.txt"; ++ if (!trace_output) ++ trace_output = "timerlat_trace.txt"; + + break; + case '5': +-- +2.51.0 + diff --git a/queue-6.18/rtla-tests-extend-action-tests-to-5s.patch b/queue-6.18/rtla-tests-extend-action-tests-to-5s.patch new file mode 100644 index 0000000000..60fdf84983 --- /dev/null +++ b/queue-6.18/rtla-tests-extend-action-tests-to-5s.patch @@ -0,0 +1,64 @@ +From 29f750a60e179e8106e1252ee21b8ad82a2ca247 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 11:53:40 +0200 +Subject: rtla/tests: Extend action tests to 5s + +From: Tomas Glozar + +[ Upstream commit d649e9f04cb0224817dac8190461ef1674e32b37 ] + +In non-BPF mode, it takes up to 1 second for RTLA to notice that tracing +has been stopped. That means that action tests cannot have a 1 second +duration, as the SIGALRM will be racing with the threshold overflow. + +Previously, non-BPF mode actions were buggy and always executed +the action, even when stopping on duration or SIGINT, preventing +this issue from manifesting. Now that this has been fixed, the tests +have become flaky, and this has to be adjusted. + +Fixes: 4e26f84abfbb ("rtla/tests: Add tests for actions") +Fixes: 05b7e10687c6 ("tools/rtla: Add remaining support for osnoise actions") +Reviewed-by: Wander Lairson Costa +Link: https://lore.kernel.org/r/20251007095341.186923-2-tglozar@redhat.com +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/tests/osnoise.t | 4 ++-- + tools/tracing/rtla/tests/timerlat.t | 4 ++-- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/tracing/rtla/tests/osnoise.t b/tools/tracing/rtla/tests/osnoise.t +index e3c89d45a6bb0..08196443fef16 100644 +--- a/tools/tracing/rtla/tests/osnoise.t ++++ b/tools/tracing/rtla/tests/osnoise.t +@@ -39,9 +39,9 @@ check "hist stop at failed action" \ + check "top stop at failed action" \ + "timerlat top -T 2 --on-threshold shell,command='echo -n abc; false' --on-threshold shell,command='echo -n defgh'" 2 "^abc" "defgh" + check "hist with continue" \ +- "osnoise hist -S 2 -d 1s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" ++ "osnoise hist -S 2 -d 5s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" + check "top with continue" \ +- "osnoise top -q -S 2 -d 1s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" ++ "osnoise top -q -S 2 -d 5s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" + check "hist with trace output at end" \ + "osnoise hist -d 1s --on-end trace" 0 "^ Saving trace to osnoise_trace.txt$" + check "top with trace output at end" \ +diff --git a/tools/tracing/rtla/tests/timerlat.t b/tools/tracing/rtla/tests/timerlat.t +index b5d1e7260a9be..b550a6ae24456 100644 +--- a/tools/tracing/rtla/tests/timerlat.t ++++ b/tools/tracing/rtla/tests/timerlat.t +@@ -60,9 +60,9 @@ check "hist stop at failed action" \ + check "top stop at failed action" \ + "timerlat top -T 2 --on-threshold shell,command='echo -n 1; false' --on-threshold shell,command='echo -n 2'" 2 "^1ALL" + check "hist with continue" \ +- "timerlat hist -T 2 -d 1s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" ++ "timerlat hist -T 2 -d 5s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" + check "top with continue" \ +- "timerlat top -q -T 2 -d 1s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" ++ "timerlat top -q -T 2 -d 5s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" + check "hist with trace output at end" \ + "timerlat hist -d 1s --on-end trace" 0 "^ Saving trace to timerlat_trace.txt$" + check "top with trace output at end" \ +-- +2.51.0 + diff --git a/queue-6.18/rtla-tests-fix-osnoise-test-calling-timerlat.patch b/queue-6.18/rtla-tests-fix-osnoise-test-calling-timerlat.patch new file mode 100644 index 0000000000..ef48a708ba --- /dev/null +++ b/queue-6.18/rtla-tests-fix-osnoise-test-calling-timerlat.patch @@ -0,0 +1,39 @@ +From edd3480b81d4b20ca43df867a0fe6159f234256d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 11:53:41 +0200 +Subject: rtla/tests: Fix osnoise test calling timerlat + +From: Tomas Glozar + +[ Upstream commit 34c170ae5c3036ef879567a37409a2859e327342 ] + +osnoise test "top stop at failed action" is calling timerlat instead of +osnoise by mistake. + +Fix it so that it calls the correct RTLA subcommand. + +Fixes: 05b7e10687c6 ("tools/rtla: Add remaining support for osnoise actions") +Reviewed-by: Wander Lairson Costa +Link: https://lore.kernel.org/r/20251007095341.186923-3-tglozar@redhat.com +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/tests/osnoise.t | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/tracing/rtla/tests/osnoise.t b/tools/tracing/rtla/tests/osnoise.t +index 08196443fef16..3963346089207 100644 +--- a/tools/tracing/rtla/tests/osnoise.t ++++ b/tools/tracing/rtla/tests/osnoise.t +@@ -37,7 +37,7 @@ check "multiple actions" \ + check "hist stop at failed action" \ + "osnoise hist -S 2 --on-threshold shell,command='echo -n 1; false' --on-threshold shell,command='echo -n 2'" 2 "^1# RTLA osnoise histogram$" + check "top stop at failed action" \ +- "timerlat top -T 2 --on-threshold shell,command='echo -n abc; false' --on-threshold shell,command='echo -n defgh'" 2 "^abc" "defgh" ++ "osnoise top -S 2 --on-threshold shell,command='echo -n abc; false' --on-threshold shell,command='echo -n defgh'" 2 "^abc" "defgh" + check "hist with continue" \ + "osnoise hist -S 2 -d 5s --on-threshold shell,command='echo TestOutput' --on-threshold continue" 0 "^TestOutput$" + check "top with continue" \ +-- +2.51.0 + diff --git a/queue-6.18/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-6.18/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..435beebd99 --- /dev/null +++ b/queue-6.18/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From e9fd3d14f66774b501a4d11eacf518aa5f0d69b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 65f1a127cc3f6..dfd5d0f61a70d 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -2484,15 +2484,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-6.18/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch b/queue-6.18/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch new file mode 100644 index 0000000000..cb0feb15da --- /dev/null +++ b/queue-6.18/s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch @@ -0,0 +1,160 @@ +From 90980e244c156b929a3c8502688e7ab6a2e88bca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 16:59:16 +0100 +Subject: s390/fpu: Fix false-positive kmsan report in fpu_vstl() + +From: Aleksei Nikiforov + +[ Upstream commit 14e4e4175b64dd9216b522f6ece8af6997d063b2 ] + +A false-positive kmsan report is detected when running ping command. + +An inline assembly instruction 'vstl' can write varied amount of bytes +depending on value of 'index' argument. If 'index' > 0, 'vstl' writes +at least 2 bytes. + +clang generates kmsan write helper call depending on inline assembly +constraints. Constraints are evaluated compile-time, but value of +'index' argument is known only at runtime. + +clang currently generates call to __msan_instrument_asm_store with 1 byte +as size. Manually call kmsan function to indicate correct amount of bytes +written and fix false-positive report. + +This change fixes following kmsan reports: + +[ 36.563119] ===================================================== +[ 36.563594] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 36.563852] virtqueue_add+0x35c6/0x7c70 +[ 36.564016] virtqueue_add_outbuf+0xa0/0xb0 +[ 36.564266] start_xmit+0x288c/0x4a20 +[ 36.564460] dev_hard_start_xmit+0x302/0x900 +[ 36.564649] sch_direct_xmit+0x340/0xea0 +[ 36.564894] __dev_queue_xmit+0x2e94/0x59b0 +[ 36.565058] neigh_resolve_output+0x936/0xb40 +[ 36.565278] __neigh_update+0x2f66/0x3a60 +[ 36.565499] neigh_update+0x52/0x60 +[ 36.565683] arp_process+0x1588/0x2de0 +[ 36.565916] NF_HOOK+0x1da/0x240 +[ 36.566087] arp_rcv+0x3e4/0x6e0 +[ 36.566306] __netif_receive_skb_list_core+0x1374/0x15a0 +[ 36.566527] netif_receive_skb_list_internal+0x1116/0x17d0 +[ 36.566710] napi_complete_done+0x376/0x740 +[ 36.566918] virtnet_poll+0x1bae/0x2910 +[ 36.567130] __napi_poll+0xf4/0x830 +[ 36.567294] net_rx_action+0x97c/0x1ed0 +[ 36.567556] handle_softirqs+0x306/0xe10 +[ 36.567731] irq_exit_rcu+0x14c/0x2e0 +[ 36.567910] do_io_irq+0xd4/0x120 +[ 36.568139] io_int_handler+0xc2/0xe8 +[ 36.568299] arch_cpu_idle+0xb0/0xc0 +[ 36.568540] arch_cpu_idle+0x76/0xc0 +[ 36.568726] default_idle_call+0x40/0x70 +[ 36.568953] do_idle+0x1d6/0x390 +[ 36.569486] cpu_startup_entry+0x9a/0xb0 +[ 36.569745] rest_init+0x1ea/0x290 +[ 36.570029] start_kernel+0x95e/0xb90 +[ 36.570348] startup_continue+0x2e/0x40 +[ 36.570703] +[ 36.570798] Uninit was created at: +[ 36.571002] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 36.571261] kmalloc_reserve+0x12a/0x470 +[ 36.571553] __alloc_skb+0x310/0x860 +[ 36.571844] __ip_append_data+0x483e/0x6a30 +[ 36.572170] ip_append_data+0x11c/0x1e0 +[ 36.572477] raw_sendmsg+0x1c8c/0x2180 +[ 36.572818] inet_sendmsg+0xe6/0x190 +[ 36.573142] __sys_sendto+0x55e/0x8e0 +[ 36.573392] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 36.573571] __do_syscall+0x12e/0x240 +[ 36.573823] system_call+0x6e/0x90 +[ 36.573976] +[ 36.574017] Byte 35 of 98 is uninitialized +[ 36.574082] Memory access of size 98 starts at 0000000007aa0012 +[ 36.574218] +[ 36.574325] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G B N 6.17.0-dirty #16 NONE +[ 36.574541] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 36.574617] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 36.574755] ===================================================== + +[ 63.532541] ===================================================== +[ 63.533639] BUG: KMSAN: uninit-value in virtqueue_add+0x35c6/0x7c70 +[ 63.533989] virtqueue_add+0x35c6/0x7c70 +[ 63.534940] virtqueue_add_outbuf+0xa0/0xb0 +[ 63.535861] start_xmit+0x288c/0x4a20 +[ 63.536708] dev_hard_start_xmit+0x302/0x900 +[ 63.537020] sch_direct_xmit+0x340/0xea0 +[ 63.537997] __dev_queue_xmit+0x2e94/0x59b0 +[ 63.538819] neigh_resolve_output+0x936/0xb40 +[ 63.539793] ip_finish_output2+0x1ee2/0x2200 +[ 63.540784] __ip_finish_output+0x272/0x7a0 +[ 63.541765] ip_finish_output+0x4e/0x5e0 +[ 63.542791] ip_output+0x166/0x410 +[ 63.543771] ip_push_pending_frames+0x1a2/0x470 +[ 63.544753] raw_sendmsg+0x1f06/0x2180 +[ 63.545033] inet_sendmsg+0xe6/0x190 +[ 63.546006] __sys_sendto+0x55e/0x8e0 +[ 63.546859] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.547730] __do_syscall+0x12e/0x240 +[ 63.548019] system_call+0x6e/0x90 +[ 63.548989] +[ 63.549779] Uninit was created at: +[ 63.550691] kmem_cache_alloc_node_noprof+0x9e8/0x10e0 +[ 63.550975] kmalloc_reserve+0x12a/0x470 +[ 63.551969] __alloc_skb+0x310/0x860 +[ 63.552949] __ip_append_data+0x483e/0x6a30 +[ 63.553902] ip_append_data+0x11c/0x1e0 +[ 63.554912] raw_sendmsg+0x1c8c/0x2180 +[ 63.556719] inet_sendmsg+0xe6/0x190 +[ 63.557534] __sys_sendto+0x55e/0x8e0 +[ 63.557875] __s390x_sys_socketcall+0x19ae/0x2ba0 +[ 63.558869] __do_syscall+0x12e/0x240 +[ 63.559832] system_call+0x6e/0x90 +[ 63.560780] +[ 63.560972] Byte 35 of 98 is uninitialized +[ 63.561741] Memory access of size 98 starts at 0000000005704312 +[ 63.561950] +[ 63.562824] CPU: 3 UID: 0 PID: 192 Comm: ping Tainted: G B N 6.17.0-dirty #16 NONE +[ 63.563868] Tainted: [B]=BAD_PAGE, [N]=TEST +[ 63.564751] Hardware name: IBM 3931 A01 703 (KVM/Linux) +[ 63.564986] ===================================================== + +Fixes: dcd3e1de9d17 ("s390/checksum: provide csum_partial_copy_nocheck()") +Signed-off-by: Aleksei Nikiforov +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/include/asm/fpu-insn.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/s390/include/asm/fpu-insn.h b/arch/s390/include/asm/fpu-insn.h +index e99f8bca8e08c..96727f3bd0dce 100644 +--- a/arch/s390/include/asm/fpu-insn.h ++++ b/arch/s390/include/asm/fpu-insn.h +@@ -12,6 +12,7 @@ + #ifndef __ASSEMBLER__ + + #include ++#include + #include + + asm(".include \"asm/fpu-insn-asm.h\"\n"); +@@ -393,6 +394,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) + : [vxr] "=Q" (*(u8 *)vxr) + : [index] "d" (index), [v1] "I" (v1) + : "memory"); ++ kmsan_unpoison_memory(vxr, size); + } + + #else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ +@@ -409,6 +411,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr) + : [vxr] "=R" (*(u8 *)vxr) + : [index] "d" (index), [v1] "I" (v1) + : "memory", "1"); ++ kmsan_unpoison_memory(vxr, size); + } + + #endif /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */ +-- +2.51.0 + diff --git a/queue-6.18/s390-smp-fix-fallback-cpu-detection.patch b/queue-6.18/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..be267e8466 --- /dev/null +++ b/queue-6.18/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From c8ccd96a193232acd548cbd50e2a7d5bfc9ef7c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index da84c0dc6b7e0..70df4ca5d4436 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -697,6 +697,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-6.18/sched-core-fix-psi_dequeue-for-proxy-execution.patch b/queue-6.18/sched-core-fix-psi_dequeue-for-proxy-execution.patch new file mode 100644 index 0000000000..72a7786295 --- /dev/null +++ b/queue-6.18/sched-core-fix-psi_dequeue-for-proxy-execution.patch @@ -0,0 +1,82 @@ +From 9011cd7bd88a07e97404c841730f95c532d0f631 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Dec 2025 01:27:09 +0000 +Subject: sched/core: Fix psi_dequeue() for Proxy Execution + +From: John Stultz + +[ Upstream commit c2ae8b0df2d1bb7a063f9e356e4e9a06cd4afe11 ] + +Currently, if the sleep flag is set, psi_dequeue() doesn't +change any of the psi_flags. + +This is because psi_task_switch() will clear TSK_ONCPU as well +as other potential flags (TSK_RUNNING), and the assumption is +that a voluntary sleep always consists of a task being dequeued +followed shortly there after with a psi_sched_switch() call. + +Proxy Execution changes this expectation, as mutex-blocked tasks +that would normally sleep stay on the runqueue. But in the case +where the mutex-owning task goes to sleep, or the owner is on a +remote cpu, we will then deactivate the blocked task shortly +after. + +In that situation, the mutex-blocked task will have had its +TSK_ONCPU cleared when it was switched off the cpu, but it will +stay TSK_RUNNING. Then if we later dequeue it (as currently done +if we hit a case find_proxy_task() can't yet handle, such as the +case of the owner being on another rq or a sleeping owner) +psi_dequeue() won't change any state (leaving it TSK_RUNNING), +as it incorrectly expects a psi_task_switch() call to +immediately follow. + +Later on when the task get woken/re-enqueued, and psi_flags are +set for TSK_RUNNING, we hit an error as the task is already +TSK_RUNNING: + + psi: inconsistent task state! task=188:kworker/28:0 cpu=28 psi_flags=4 clear=0 set=4 + +To resolve this, extend the logic in psi_dequeue() so that +if the sleep flag is set, we also check if psi_flags have +TSK_ONCPU set (meaning the psi_task_switch is imminent) before +we do the shortcut return. + +If TSK_ONCPU is not set, that means we've already switched away, +and this psi_dequeue call needs to clear the flags. + +Fixes: be41bde4c3a8 ("sched: Add an initial sketch of the find_proxy_task() function") +Reported-by: K Prateek Nayak +Signed-off-by: John Stultz +Signed-off-by: Ingo Molnar +Tested-by: K Prateek Nayak +Tested-by: Haiyue Wang +Acked-by: Johannes Weiner +Link: https://patch.msgid.link/20251205012721.756394-1-jstultz@google.com +Closes: https://lore.kernel.org/lkml/20251117185550.365156-1-kprateek.nayak@amd.com/ +Signed-off-by: Sasha Levin +--- + kernel/sched/stats.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h +index 26f3fd4d34cea..73bd6bca4d310 100644 +--- a/kernel/sched/stats.h ++++ b/kernel/sched/stats.h +@@ -180,8 +180,13 @@ static inline void psi_dequeue(struct task_struct *p, int flags) + * avoid walking all ancestors twice, psi_task_switch() handles + * TSK_RUNNING and TSK_IOWAIT for us when it moves TSK_ONCPU. + * Do nothing here. ++ * ++ * In the SCHED_PROXY_EXECUTION case we may do sleeping ++ * dequeues that are not followed by a task switch, so check ++ * TSK_ONCPU is set to ensure the task switch is imminent. ++ * Otherwise clear the flags as usual. + */ +- if (flags & DEQUEUE_SLEEP) ++ if ((flags & DEQUEUE_SLEEP) && (p->psi_flags & TSK_ONCPU)) + return; + + /* +-- +2.51.0 + diff --git a/queue-6.18/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch b/queue-6.18/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch new file mode 100644 index 0000000000..53348e229d --- /dev/null +++ b/queue-6.18/sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch @@ -0,0 +1,57 @@ +From 71e6716c0b4c414a65f26d0f7bd5851b7507069b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 27 Aug 2025 10:22:07 +0800 +Subject: sched/fair: Fix unfairness caused by stalled tg_load_avg_contrib when + the last task migrates out + +From: xupengbo + +[ Upstream commit ca125231dd29fc0678dd3622e9cdea80a51dffe4 ] + +When a task is migrated out, there is a probability that the tg->load_avg +value will become abnormal. The reason is as follows: + +1. Due to the 1ms update period limitation in update_tg_load_avg(), there + is a possibility that the reduced load_avg is not updated to tg->load_avg + when a task migrates out. + +2. Even though __update_blocked_fair() traverses the leaf_cfs_rq_list and + calls update_tg_load_avg() for cfs_rqs that are not fully decayed, the key + function cfs_rq_is_decayed() does not check whether + cfs->tg_load_avg_contrib is null. Consequently, in some cases, + __update_blocked_fair() removes cfs_rqs whose avg.load_avg has not been + updated to tg->load_avg. + +Add a check of cfs_rq->tg_load_avg_contrib in cfs_rq_is_decayed(), +which fixes the case (2.) mentioned above. + +Fixes: 1528c661c24b ("sched/fair: Ratelimit update to tg->load_avg") +Signed-off-by: xupengbo +Signed-off-by: Peter Zijlstra (Intel) +Signed-off-by: Ingo Molnar +Reviewed-by: Aaron Lu +Reviewed-by: Vincent Guittot +Tested-by: Aaron Lu +Link: https://patch.msgid.link/20250827022208.14487-1-xupengbo@oppo.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 2a4a1c6e25da0..71d3f4125b0e7 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4059,6 +4059,9 @@ static inline bool cfs_rq_is_decayed(struct cfs_rq *cfs_rq) + if (child_cfs_rq_on_list(cfs_rq)) + return false; + ++ if (cfs_rq->tg_load_avg_contrib) ++ return false; ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.18/sched-fair-forfeit-vruntime-on-yield.patch b/queue-6.18/sched-fair-forfeit-vruntime-on-yield.patch new file mode 100644 index 0000000000..fc1a488c95 --- /dev/null +++ b/queue-6.18/sched-fair-forfeit-vruntime-on-yield.patch @@ -0,0 +1,68 @@ +From c7a5238601bfbf2e2491fa92bbbcaa6f8e616dac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:05:28 +0200 +Subject: sched/fair: Forfeit vruntime on yield + +From: Fernand Sieber + +[ Upstream commit 79104becf42baeeb4a3f2b106f954b9fc7c10a3c ] + +If a task yields, the scheduler may decide to pick it again. The task in +turn may decide to yield immediately or shortly after, leading to a tight +loop of yields. + +If there's another runnable task as this point, the deadline will be +increased by the slice at each loop. This can cause the deadline to runaway +pretty quickly, and subsequent elevated run delays later on as the task +doesn't get picked again. The reason the scheduler can pick the same task +again and again despite its deadline increasing is because it may be the +only eligible task at that point. + +Fix this by making the task forfeiting its remaining vruntime and pushing +the deadline one slice ahead. This implements yield behavior more +authentically. + +We limit the forfeiting to eligible tasks. This is because core scheduling +prefers running ineligible tasks rather than force idling. As such, without +the condition, we can end up on a yield loop which makes the vruntime +increase rapidly, leading to anomalous run delays later down the line. + +Fixes: 147f3efaa24182 ("sched/fair: Implement an EEVDF-like scheduling policy") +Signed-off-by: Fernand Sieber +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20250401123622.584018-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250911095113.203439-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250916140228.452231-1-sieberf@amazon.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 5b752324270b0..2a4a1c6e25da0 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -9014,7 +9014,19 @@ static void yield_task_fair(struct rq *rq) + */ + rq_clock_skip_update(rq); + +- se->deadline += calc_delta_fair(se->slice, se); ++ /* ++ * Forfeit the remaining vruntime, only if the entity is eligible. This ++ * condition is necessary because in core scheduling we prefer to run ++ * ineligible tasks rather than force idling. If this happens we may ++ * end up in a loop where the core scheduler picks the yielding task, ++ * which yields immediately again; without the condition the vruntime ++ * ends up quickly running away. ++ */ ++ if (entity_eligible(cfs_rq, se)) { ++ se->vruntime = se->deadline; ++ se->deadline += calc_delta_fair(se->slice, se); ++ update_min_vruntime(cfs_rq); ++ } + } + + static bool yield_to_task_fair(struct rq *rq, struct task_struct *p) +-- +2.51.0 + diff --git a/queue-6.18/scsi-qla2xxx-clear-cmds-after-chip-reset.patch b/queue-6.18/scsi-qla2xxx-clear-cmds-after-chip-reset.patch new file mode 100644 index 0000000000..c43c39c61d --- /dev/null +++ b/queue-6.18/scsi-qla2xxx-clear-cmds-after-chip-reset.patch @@ -0,0 +1,111 @@ +From dc6416d9e37a52e1a114b96decc296b8db9ae8d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 11:07:37 -0500 +Subject: scsi: qla2xxx: Clear cmds after chip reset + +From: Tony Battersby + +[ Upstream commit d46c69a087aa3d1513f7a78f871b80251ea0c1ae ] + +Commit aefed3e5548f ("scsi: qla2xxx: target: Fix offline port handling +and host reset handling") caused two problems: + +1. Commands sent to FW, after chip reset got stuck and never freed as FW + is not going to respond to them anymore. + +2. BUG_ON(cmd->sg_mapped) in qlt_free_cmd(). Commit 26f9ce53817a + ("scsi: qla2xxx: Fix missed DMA unmap for aborted commands") + attempted to fix this, but introduced another bug under different + circumstances when two different CPUs were racing to call + qlt_unmap_sg() at the same time: BUG_ON(!valid_dma_direction(dir)) in + dma_unmap_sg_attrs(). + +So revert "scsi: qla2xxx: Fix missed DMA unmap for aborted commands" and +partially revert "scsi: qla2xxx: target: Fix offline port handling and +host reset handling" at __qla2x00_abort_all_cmds. + +Fixes: aefed3e5548f ("scsi: qla2xxx: target: Fix offline port handling and host reset handling") +Fixes: 26f9ce53817a ("scsi: qla2xxx: Fix missed DMA unmap for aborted commands") +Co-developed-by: Dmitry Bogdanov +Signed-off-by: Dmitry Bogdanov +Signed-off-by: Tony Battersby +Link: https://patch.msgid.link/0e7e5d26-e7a0-42d1-8235-40eeb27f3e98@cybernetics.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_os.c | 20 ++++++++++++++++++-- + drivers/scsi/qla2xxx/qla_target.c | 5 +---- + drivers/scsi/qla2xxx/qla_target.h | 1 + + 3 files changed, 20 insertions(+), 6 deletions(-) + +diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c +index 5ffd945866527..70a579cf9c3fd 100644 +--- a/drivers/scsi/qla2xxx/qla_os.c ++++ b/drivers/scsi/qla2xxx/qla_os.c +@@ -1881,10 +1881,26 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) + continue; + } + cmd = (struct qla_tgt_cmd *)sp; +- cmd->aborted = 1; ++ ++ if (cmd->sg_mapped) ++ qlt_unmap_sg(vha, cmd); ++ ++ if (cmd->state == QLA_TGT_STATE_NEED_DATA) { ++ cmd->aborted = 1; ++ cmd->write_data_transferred = 0; ++ cmd->state = QLA_TGT_STATE_DATA_IN; ++ ha->tgt.tgt_ops->handle_data(cmd); ++ } else { ++ ha->tgt.tgt_ops->free_cmd(cmd); ++ } + break; + case TYPE_TGT_TMCMD: +- /* Skip task management functions. */ ++ /* ++ * Currently, only ABTS response gets on the ++ * outstanding_cmds[] ++ */ ++ ha->tgt.tgt_ops->free_mcmd( ++ (struct qla_tgt_mgmt_cmd *) sp); + break; + default: + break; +diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c +index 1e81582085e38..4c6aff59fe3fb 100644 +--- a/drivers/scsi/qla2xxx/qla_target.c ++++ b/drivers/scsi/qla2xxx/qla_target.c +@@ -2443,7 +2443,7 @@ static int qlt_pci_map_calc_cnt(struct qla_tgt_prm *prm) + return -1; + } + +-static void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) ++void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd) + { + struct qla_hw_data *ha; + struct qla_qpair *qpair; +@@ -3773,9 +3773,6 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd) + + spin_lock_irqsave(&cmd->cmd_lock, flags); + if (cmd->aborted) { +- if (cmd->sg_mapped) +- qlt_unmap_sg(vha, cmd); +- + spin_unlock_irqrestore(&cmd->cmd_lock, flags); + /* + * It's normal to see 2 calls in this path: +diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h +index 15a59c125c532..c483966d0a847 100644 +--- a/drivers/scsi/qla2xxx/qla_target.h ++++ b/drivers/scsi/qla2xxx/qla_target.h +@@ -1058,6 +1058,7 @@ extern int qlt_abort_cmd(struct qla_tgt_cmd *); + extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *); + extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *); + extern void qlt_free_cmd(struct qla_tgt_cmd *cmd); ++extern void qlt_unmap_sg(struct scsi_qla_host *vha, struct qla_tgt_cmd *cmd); + extern void qlt_async_event(uint16_t, struct scsi_qla_host *, uint16_t *); + extern void qlt_enable_vha(struct scsi_qla_host *); + extern void qlt_vport_create(struct scsi_qla_host *, struct qla_hw_data *); +-- +2.51.0 + diff --git a/queue-6.18/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch b/queue-6.18/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch new file mode 100644 index 0000000000..d56a34287d --- /dev/null +++ b/queue-6.18/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch @@ -0,0 +1,51 @@ +From 7a2fd87efa45495c87b1af7a16992b1f908a0324 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 15:12:46 +0000 +Subject: scsi: qla2xxx: Fix improper freeing of purex item + +From: Zilin Guan + +[ Upstream commit 78b1a242fe612a755f2158fd206ee6bb577d18ca ] + +In qla2xxx_process_purls_iocb(), an item is allocated via +qla27xx_copy_multiple_pkt(), which internally calls +qla24xx_alloc_purex_item(). + +The qla24xx_alloc_purex_item() function may return a pre-allocated item +from a per-adapter pool for small allocations, instead of dynamically +allocating memory with kzalloc(). + +An error handling path in qla2xxx_process_purls_iocb() incorrectly uses +kfree() to release the item. If the item was from the pre-allocated +pool, calling kfree() on it is a bug that can lead to memory corruption. + +Fix this by using the correct deallocation function, +qla24xx_free_purex_item(), which properly handles both dynamically +allocated and pre-allocated items. + +Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") +Signed-off-by: Zilin Guan +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_nvme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 316594aa40cc5..42eb65a62f1f3 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -1292,7 +1292,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) + a.reason = FCNVME_RJT_RC_LOGIC; + a.explanation = FCNVME_RJT_EXP_NONE; + xmt_reject = true; +- kfree(item); ++ qla24xx_free_purex_item(item); + goto out; + } + +-- +2.51.0 + diff --git a/queue-6.18/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-6.18/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..01f6cba32f --- /dev/null +++ b/queue-6.18/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From b346cce9f9ec19b87ea757340c561dae17e6ac83 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-6.18/scsi-smartpqi-fix-device-resources-accessed-after-de.patch b/queue-6.18/scsi-smartpqi-fix-device-resources-accessed-after-de.patch new file mode 100644 index 0000000000..4244706b5d --- /dev/null +++ b/queue-6.18/scsi-smartpqi-fix-device-resources-accessed-after-de.patch @@ -0,0 +1,94 @@ +From eb7f151e3446c1f15b879dae3b82152ba648f295 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 10:38:20 -0600 +Subject: scsi: smartpqi: Fix device resources accessed after device removal + +From: Mike McGowen + +[ Upstream commit b518e86d1a70a88f6592a7c396cf1b93493d1aab ] + +Correct possible race conditions during device removal. + +Previously, a scheduled work item to reset a LUN could still execute +after the device was removed, leading to use-after-free and other +resource access issues. + +This race condition occurs because the abort handler may schedule a LUN +reset concurrently with device removal via sdev_destroy(), leading to +use-after-free and improper access to freed resources. + + - Check in the device reset handler if the device is still present in + the controller's SCSI device list before running; if not, the reset + is skipped. + + - Cancel any pending TMF work that has not started in sdev_destroy(). + + - Ensure device freeing in sdev_destroy() is done while holding the + LUN reset mutex to avoid races with ongoing resets. + +Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 03c97e60d36f6..fdc856845a05d 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6410,10 +6410,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev + + static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { ++ unsigned long flags; + int rc; + + mutex_lock(&ctrl_info->lun_reset_mutex); + ++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); ++ if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { ++ dev_warn(&ctrl_info->pci_dev->dev, ++ "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%u SCSI cmd at %p due to cmd opcode 0x%02x\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, lun, scmd, scsi_opcode); +@@ -6594,7 +6606,9 @@ static void pqi_sdev_destroy(struct scsi_device *sdev) + { + struct pqi_ctrl_info *ctrl_info; + struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; + int mutex_acquired; ++ unsigned int lun; + unsigned long flags; + + ctrl_info = shost_to_hba(sdev->host); +@@ -6621,8 +6635,13 @@ static void pqi_sdev_destroy(struct scsi_device *sdev) + + mutex_unlock(&ctrl_info->scan_mutex); + ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ cancel_work_sync(&tmf_work->work_struct); ++ ++ mutex_lock(&ctrl_info->lun_reset_mutex); + pqi_dev_info(ctrl_info, "removed", device); + pqi_free_device(device); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); + } + + static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) +-- +2.51.0 + diff --git a/queue-6.18/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-6.18/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..6dad2e055c --- /dev/null +++ b/queue-6.18/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From 1a1a7ebf98bb6aabad406dc228079c9d5f835939 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index d8ad02c293205..e02f28e5a104e 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1844,6 +1844,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-6.18/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-6.18/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..6a6640e144 --- /dev/null +++ b/queue-6.18/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From bb98851b1b2526207c006adec0d8ea470cfcfa26 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index b19acd662726d..1bd28482e7cb3 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2772,7 +2772,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-6.18/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch b/queue-6.18/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch new file mode 100644 index 0000000000..ed5b8c7137 --- /dev/null +++ b/queue-6.18/scsi-target-fix-lun-device-r-w-and-total-command-sta.patch @@ -0,0 +1,171 @@ +From 245f23a41729c0dfb4a6bcb55b2fe32261bc00c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 17:12:53 -0500 +Subject: scsi: target: Fix LUN/device R/W and total command stats + +From: Mike Christie + +[ Upstream commit 95aa2041c654161d1b5c1eca5379d67d91ef1cf2 ] + +In commit 9cf2317b795d ("scsi: target: Move I/O path stats to per CPU") +I saw we sometimes use %u and also misread the spec. As a result I +thought all the stats were supposed to be 32-bit only. However, for the +majority of cases we support currently, the spec specifies u64 bit +stats. This patch converts the stats changed in the commit above to u64. + +Fixes: 9cf2317b795d ("scsi: target: Move I/O path stats to per CPU") +Signed-off-by: Mike Christie +Reviewed-by: Dmitry Bogdanov +Link: https://patch.msgid.link/20250917221338.14813-2-michael.christie@oracle.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_stat.c | 24 ++++++++++++------------ + include/target/target_core_base.h | 12 ++++++------ + 2 files changed, 18 insertions(+), 18 deletions(-) + +diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c +index 6bdf2d8bd6942..4fdc307ea38bc 100644 +--- a/drivers/target/target_core_stat.c ++++ b/drivers/target/target_core_stat.c +@@ -282,7 +282,7 @@ static ssize_t target_stat_lu_num_cmds_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 cmds = 0; ++ u64 cmds = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -290,7 +290,7 @@ static ssize_t target_stat_lu_num_cmds_show(struct config_item *item, + } + + /* scsiLuNumCommands */ +- return snprintf(page, PAGE_SIZE, "%u\n", cmds); ++ return snprintf(page, PAGE_SIZE, "%llu\n", cmds); + } + + static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, +@@ -299,7 +299,7 @@ static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 bytes = 0; ++ u64 bytes = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -307,7 +307,7 @@ static ssize_t target_stat_lu_read_mbytes_show(struct config_item *item, + } + + /* scsiLuReadMegaBytes */ +- return snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ return snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + } + + static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, +@@ -316,7 +316,7 @@ static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, + struct se_device *dev = to_stat_lu_dev(item); + struct se_dev_io_stats *stats; + unsigned int cpu; +- u32 bytes = 0; ++ u64 bytes = 0; + + for_each_possible_cpu(cpu) { + stats = per_cpu_ptr(dev->stats, cpu); +@@ -324,7 +324,7 @@ static ssize_t target_stat_lu_write_mbytes_show(struct config_item *item, + } + + /* scsiLuWrittenMegaBytes */ +- return snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ return snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + } + + static ssize_t target_stat_lu_resets_show(struct config_item *item, char *page) +@@ -1044,7 +1044,7 @@ static ssize_t target_stat_auth_num_cmds_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 cmds = 0; ++ u64 cmds = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1059,7 +1059,7 @@ static ssize_t target_stat_auth_num_cmds_show(struct config_item *item, + } + + /* scsiAuthIntrOutCommands */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", cmds); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", cmds); + rcu_read_unlock(); + return ret; + } +@@ -1073,7 +1073,7 @@ static ssize_t target_stat_auth_read_mbytes_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 bytes = 0; ++ u64 bytes = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1088,7 +1088,7 @@ static ssize_t target_stat_auth_read_mbytes_show(struct config_item *item, + } + + /* scsiAuthIntrReadMegaBytes */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + rcu_read_unlock(); + return ret; + } +@@ -1102,7 +1102,7 @@ static ssize_t target_stat_auth_write_mbytes_show(struct config_item *item, + struct se_dev_entry *deve; + unsigned int cpu; + ssize_t ret; +- u32 bytes = 0; ++ u64 bytes = 0; + + rcu_read_lock(); + deve = target_nacl_find_deve(nacl, lacl->mapped_lun); +@@ -1117,7 +1117,7 @@ static ssize_t target_stat_auth_write_mbytes_show(struct config_item *item, + } + + /* scsiAuthIntrWrittenMegaBytes */ +- ret = snprintf(page, PAGE_SIZE, "%u\n", bytes >> 20); ++ ret = snprintf(page, PAGE_SIZE, "%llu\n", bytes >> 20); + rcu_read_unlock(); + return ret; + } +diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h +index c4d9116904aa0..27e1f9d5f0c6c 100644 +--- a/include/target/target_core_base.h ++++ b/include/target/target_core_base.h +@@ -671,9 +671,9 @@ struct se_lun_acl { + }; + + struct se_dev_entry_io_stats { +- u32 total_cmds; +- u32 read_bytes; +- u32 write_bytes; ++ u64 total_cmds; ++ u64 read_bytes; ++ u64 write_bytes; + }; + + struct se_dev_entry { +@@ -806,9 +806,9 @@ struct se_device_queue { + }; + + struct se_dev_io_stats { +- u32 total_cmds; +- u32 read_bytes; +- u32 write_bytes; ++ u64 total_cmds; ++ u64 read_bytes; ++ u64 write_bytes; + }; + + struct se_device { +-- +2.51.0 + diff --git a/queue-6.18/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch b/queue-6.18/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch new file mode 100644 index 0000000000..73d87def7b --- /dev/null +++ b/queue-6.18/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch @@ -0,0 +1,46 @@ +From 7121495fc6b5ea353be7482ccac0e5a4a4af17a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 00:05:17 +0100 +Subject: scsi: ufs: core: fix incorrect buffer duplication in + ufshcd_read_string_desc() + +From: Bean Huo + +[ Upstream commit d794b499f948801f54d67ddbc34a6eac5a6d150a ] + +The function ufshcd_read_string_desc() was duplicating memory starting +from the beginning of struct uc_string_id, which included the length and +type fields. As a result, the allocated buffer contained unwanted +metadata in addition to the string itself. + +The correct behavior is to duplicate only the Unicode character array in +the structure. Update the code so that only the actual string content is +copied into the new buffer. + +Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Bean Huo +Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index d6a060a724618..12f5a7a973128 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3837,7 +3837,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + str[ret++] = '\0'; + + } else { +- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); ++ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + goto out; +-- +2.51.0 + diff --git a/queue-6.18/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch b/queue-6.18/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch new file mode 100644 index 0000000000..2b822b4a6f --- /dev/null +++ b/queue-6.18/scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch @@ -0,0 +1,51 @@ +From 33d9f9e9dfbdd83f32185a1cdb69f09a75547e5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 13:00:58 -0700 +Subject: scsi: ufs: core: Move the ufshcd_enable_intr() declaration + +From: Bart Van Assche + +[ Upstream commit b30006b5bec1dcba207bc42e7f7cd96a568acc27 ] + +ufshcd_enable_intr() is not exported and hence should not be declared in +include/ufs/ufshcd.h. + +Fixes: 253757797973 ("scsi: ufs: core: Change MCQ interrupt enable flow") +Signed-off-by: Bart Van Assche +Reviewed-by: Peter Wang +Link: https://patch.msgid.link/20251014200118.3390839-7-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd-priv.h | 2 ++ + include/ufs/ufshcd.h | 1 - + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd-priv.h b/drivers/ufs/core/ufshcd-priv.h +index d0a2c963a27d3..1f0d38aa37f92 100644 +--- a/drivers/ufs/core/ufshcd-priv.h ++++ b/drivers/ufs/core/ufshcd-priv.h +@@ -6,6 +6,8 @@ + #include + #include + ++void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs); ++ + static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba) + { + return !hba->shutting_down; +diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h +index 0f95576bf1f6c..d949db3a46759 100644 +--- a/include/ufs/ufshcd.h ++++ b/include/ufs/ufshcd.h +@@ -1302,7 +1302,6 @@ static inline void ufshcd_rmwl(struct ufs_hba *hba, u32 mask, u32 val, u32 reg) + + void ufshcd_enable_irq(struct ufs_hba *hba); + void ufshcd_disable_irq(struct ufs_hba *hba); +-void ufshcd_enable_intr(struct ufs_hba *hba, u32 intrs); + int ufshcd_alloc_host(struct device *, struct ufs_hba **); + int ufshcd_hba_enable(struct ufs_hba *hba); + int ufshcd_init(struct ufs_hba *, void __iomem *, unsigned int); +-- +2.51.0 + diff --git a/queue-6.18/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch b/queue-6.18/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch new file mode 100644 index 0000000000..8d7b047ae6 --- /dev/null +++ b/queue-6.18/scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch @@ -0,0 +1,87 @@ +From c3e0691307496486b0c1f28122e04dc987147c47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:55 +0800 +Subject: scsi: ufs: rockchip: Reset controller on PRE_CHANGE of hce enable + notify + +From: Shawn Lin + +[ Upstream commit b0ee72db9132bd19b1b80152b35e0cf6a6cbd9f2 ] + +This fixes the dme-reset failed when doing recovery. Because device +reset is not enough, we could occasionally see the error below: + +ufshcd-rockchip 2a2d0000.ufs: uic cmd 0x14 with arg3 0x0 completion timeout +ufshcd-rockchip 2a2d0000.ufs: dme-reset: error code -110 +ufshcd-rockchip 2a2d0000.ufs: DME_RESET failed +ufshcd-rockchip 2a2d0000.ufs: ufshcd_host_reset_and_restore: Host init failed -110 + +Fix this by resetting the controller on PRE_CHANGE stage of hce enable +notify. + +Fixes: d3cbe455d6eb ("scsi: ufs: rockchip: Initial support for UFS") +Signed-off-by: Shawn Lin +Link: https://patch.msgid.link/1763009575-237552-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/host/ufs-rockchip.c | 19 +++++++++++++------ + 1 file changed, 13 insertions(+), 6 deletions(-) + +diff --git a/drivers/ufs/host/ufs-rockchip.c b/drivers/ufs/host/ufs-rockchip.c +index 8754085dd0ccf..8cecb28cdce41 100644 +--- a/drivers/ufs/host/ufs-rockchip.c ++++ b/drivers/ufs/host/ufs-rockchip.c +@@ -20,9 +20,17 @@ + #include "ufshcd-pltfrm.h" + #include "ufs-rockchip.h" + ++static void ufs_rockchip_controller_reset(struct ufs_rockchip_host *host) ++{ ++ reset_control_assert(host->rst); ++ udelay(1); ++ reset_control_deassert(host->rst); ++} ++ + static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, + enum ufs_notify_change_status status) + { ++ struct ufs_rockchip_host *host = ufshcd_get_variant(hba); + int err = 0; + + if (status == POST_CHANGE) { +@@ -37,6 +45,9 @@ static int ufs_rockchip_hce_enable_notify(struct ufs_hba *hba, + return ufshcd_vops_phy_initialization(hba); + } + ++ /* PRE_CHANGE */ ++ ufs_rockchip_controller_reset(host); ++ + return 0; + } + +@@ -156,9 +167,7 @@ static int ufs_rockchip_common_init(struct ufs_hba *hba) + return dev_err_probe(dev, PTR_ERR(host->rst), + "failed to get reset control\n"); + +- reset_control_assert(host->rst); +- udelay(1); +- reset_control_deassert(host->rst); ++ ufs_rockchip_controller_reset(host); + + host->ref_out_clk = devm_clk_get_enabled(dev, "ref_out"); + if (IS_ERR(host->ref_out_clk)) +@@ -282,9 +291,7 @@ static int ufs_rockchip_runtime_resume(struct device *dev) + return err; + } + +- reset_control_assert(host->rst); +- udelay(1); +- reset_control_deassert(host->rst); ++ ufs_rockchip_controller_reset(host); + + return ufshcd_runtime_resume(dev); + } +-- +2.51.0 + diff --git a/queue-6.18/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-6.18/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..57c9c84f4f --- /dev/null +++ b/queue-6.18/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From ca487ca367acdb567c653f655b48b73a0b869d10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index ed8293a342402..d190e75e46454 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1553,8 +1553,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5109,9 +5107,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + static void sctp_destruct_sock(struct sock *sk) +-- +2.51.0 + diff --git a/queue-6.18/selftests-bonding-add-delay-before-each-xvlan_over_b.patch b/queue-6.18/selftests-bonding-add-delay-before-each-xvlan_over_b.patch new file mode 100644 index 0000000000..b8a015f46c --- /dev/null +++ b/queue-6.18/selftests-bonding-add-delay-before-each-xvlan_over_b.patch @@ -0,0 +1,47 @@ +From 5ad499b5b24d1f051f4fd0a449f5ac0a84cb5009 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:33:10 +0000 +Subject: selftests: bonding: add delay before each xvlan_over_bond + connectivity check + +From: Hangbin Liu + +[ Upstream commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d ] + +Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular +kernel, while the tests consistently pass on a debug kernel. This suggests +a timing-sensitive issue. + +To mitigate this, introduce a short sleep before each xvlan_over_bond +connectivity check. The delay helps ensure neighbor and route cache +have fully converged before verifying connectivity. + +The sleep interval is kept minimal since check_connection() is invoked +nearly 100 times during the test. + +Fixes: 246af950b940 ("selftests: bonding: add macvlan over bond testing") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/netdev/20251114082014.750edfad@kernel.org +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251127143310.47740-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +index c4711272fe45d..559f300f965aa 100755 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -30,6 +30,7 @@ check_connection() + local message=${3} + RET=0 + ++ sleep 0.25 + ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null + check_err $? "ping failed" + log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-allow-selftests-to-build-with-older-xx.patch b/queue-6.18/selftests-bpf-allow-selftests-to-build-with-older-xx.patch new file mode 100644 index 0000000000..f387c99440 --- /dev/null +++ b/queue-6.18/selftests-bpf-allow-selftests-to-build-with-older-xx.patch @@ -0,0 +1,67 @@ +From 8f464e7c2d8ef1e9c3ca7e645397ff95bb91e0f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 08:47:54 +0000 +Subject: selftests/bpf: Allow selftests to build with older xxd + +From: Alan Maguire + +[ Upstream commit ad93ba02678eda5fc8e259cf4b52997e6fa570cf ] + +Currently selftests require xxd with the "-n " option +which allows the user to specify a name not derived from +the input object path. Instead of relying on this newer +feature, older xxd can be used if we link our desired name +("test_progs_verification_cert") to the input object. + +Many distros ship xxd in vim-common package and do not have +the latest xxd with -n support. + +Fixes: b720903e2b14d ("selftests/bpf: Enable signature verification for some lskel tests") +Signed-off-by: Alan Maguire +Link: https://lore.kernel.org/r/20251120084754.640405-3-alan.maguire@oracle.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/.gitignore | 1 + + tools/testing/selftests/bpf/Makefile | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/.gitignore b/tools/testing/selftests/bpf/.gitignore +index be1ee7ba7ce03..ca557e5668fd8 100644 +--- a/tools/testing/selftests/bpf/.gitignore ++++ b/tools/testing/selftests/bpf/.gitignore +@@ -23,6 +23,7 @@ test_tcpnotify_user + test_libbpf + xdping + test_cpp ++test_progs_verification_cert + *.d + *.subskel.h + *.skel.h +diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile +index f00587d4ede68..e59b2bbf8d920 100644 +--- a/tools/testing/selftests/bpf/Makefile ++++ b/tools/testing/selftests/bpf/Makefile +@@ -721,7 +721,8 @@ $(VERIFICATION_CERT) $(PRIVATE_KEY): $(VERIFY_SIG_SETUP) + $(Q)$(VERIFY_SIG_SETUP) genkey $(BUILD_DIR) + + $(VERIFY_SIG_HDR): $(VERIFICATION_CERT) +- $(Q)xxd -i -n test_progs_verification_cert $< > $@ ++ $(Q)ln -fs $< test_progs_verification_cert && \ ++ xxd -i test_progs_verification_cert > $@ + + # Define test_progs test runner. + TRUNNER_TESTS_DIR := prog_tests +@@ -893,7 +894,8 @@ EXTRA_CLEAN := $(SCRATCH_DIR) $(HOST_SCRATCH_DIR) \ + $(addprefix $(OUTPUT)/,*.o *.d *.skel.h *.lskel.h *.subskel.h \ + no_alu32 cpuv4 bpf_gcc \ + liburandom_read.so) \ +- $(OUTPUT)/FEATURE-DUMP.selftests ++ $(OUTPUT)/FEATURE-DUMP.selftests \ ++ test_progs_verification_cert + + .PHONY: docs docs-clean + +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-6.18/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..a837ecadfb --- /dev/null +++ b/queue-6.18/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 14221bd76361a20fdedba3bc8f01ece696ce5f71 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 1702aa592c2c2..7ac4d5a488aa5 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -206,6 +206,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-6.18/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..f59fbf3be2 --- /dev/null +++ b/queue-6.18/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 70f209536394e46a5e775eaa4d8dbc5d41691c21 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 06c7986131d96..0a7ef770c487c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-6.18/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..7a512fe2a5 --- /dev/null +++ b/queue-6.18/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From 866325baec91e5eff94abf9a19eade78b8b4550a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index bc24f83339d64..06c7986131d96 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-update-test_tag-to-use-sha256.patch b/queue-6.18/selftests-bpf-update-test_tag-to-use-sha256.patch new file mode 100644 index 0000000000..a72a2d31e7 --- /dev/null +++ b/queue-6.18/selftests-bpf-update-test_tag-to-use-sha256.patch @@ -0,0 +1,38 @@ +From d24113a86cd385e5d5680745a1d91bae763bf469 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:14:58 +0800 +Subject: selftests/bpf: Update test_tag to use sha256 + +From: Xing Guo + +[ Upstream commit b7f7d76d6e354a5acc711da37cb2829ccf40558f ] + +commit 603b44162325 ("bpf: Update the bpf_prog_calc_tag to use SHA256") +changed digest of prog_tag to SHA256 but forgot to update tests +correspondingly. Fix it. + +Fixes: 603b44162325 ("bpf: Update the bpf_prog_calc_tag to use SHA256") +Signed-off-by: Xing Guo +Link: https://lore.kernel.org/r/20251121061458.3145167-1-higuoxing@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/test_tag.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/test_tag.c b/tools/testing/selftests/bpf/test_tag.c +index 5546b05a04866..f1300047c1e0a 100644 +--- a/tools/testing/selftests/bpf/test_tag.c ++++ b/tools/testing/selftests/bpf/test_tag.c +@@ -116,7 +116,7 @@ static void tag_from_alg(int insns, uint8_t *tag, uint32_t len) + static const struct sockaddr_alg alg = { + .salg_family = AF_ALG, + .salg_type = "hash", +- .salg_name = "sha1", ++ .salg_name = "sha256", + }; + int fd_base, fd_alg, ret; + ssize_t size; +-- +2.51.0 + diff --git a/queue-6.18/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch b/queue-6.18/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch new file mode 100644 index 0000000000..ecb00e2493 --- /dev/null +++ b/queue-6.18/selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch @@ -0,0 +1,53 @@ +From dc077bed78b1277ff46ad8ad0df8adbfb5c3f3f9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 07:37:34 +0000 +Subject: selftests/bpf: Use ASSERT_STRNEQ to factor in long slab cache names + +From: Matt Bobrowski + +[ Upstream commit d088da904223e8f5e19c6d156cf372d5baec1a7c ] + +subtest_kmem_cache_iter_check_slabinfo() fundamentally compares slab +cache names parsed out from /proc/slabinfo against those stored within +struct kmem_cache_result. The current problem is that the slab cache +name within struct kmem_cache_result is stored within a bounded +fixed-length array (sized to SLAB_NAME_MAX(32)), whereas the name +parsed out from /proc/slabinfo is not. Meaning, using ASSERT_STREQ() +can certainly lead to test failures, particularly when dealing with +slab cache names that are longer than SLAB_NAME_MAX(32) +bytes. Notably, kmem_cache_create() allows callers to create slab +caches with somewhat arbitrarily sized names via its __name identifier +argument, so exceeding the SLAB_NAME_MAX(32) limit that is in place +now can certainly happen. + +Make subtest_kmem_cache_iter_check_slabinfo() more reliable by only +checking up to sizeof(struct kmem_cache_result.name) - 1 using +ASSERT_STRNEQ(). + +Fixes: a496d0cdc84d ("selftests/bpf: Add a test for kmem_cache_iter") +Signed-off-by: Matt Bobrowski +Signed-off-by: Martin KaFai Lau +Acked-by: Song Liu +Link: https://patch.msgid.link/20251118073734.4188710-1-mattbobrowski@google.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +index 1de14b111931a..6e35e13c20220 100644 +--- a/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c ++++ b/tools/testing/selftests/bpf/prog_tests/kmem_cache_iter.c +@@ -57,7 +57,8 @@ static void subtest_kmem_cache_iter_check_slabinfo(struct kmem_cache_iter *skel) + if (!ASSERT_OK(ret, "kmem_cache_lookup")) + break; + +- ASSERT_STREQ(r.name, name, "kmem_cache_name"); ++ ASSERT_STRNEQ(r.name, name, sizeof(r.name) - 1, ++ "kmem_cache_name"); + ASSERT_EQ(r.obj_size, objsize, "kmem_cache_objsize"); + + seen++; +-- +2.51.0 + diff --git a/queue-6.18/selftests-landlock-fix-makefile-header-list.patch b/queue-6.18/selftests-landlock-fix-makefile-header-list.patch new file mode 100644 index 0000000000..6189141a79 --- /dev/null +++ b/queue-6.18/selftests-landlock-fix-makefile-header-list.patch @@ -0,0 +1,44 @@ +From a7d7fee5471ab5c059897ad6a74adb1de5697ce7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 02:14:40 +0100 +Subject: selftests/landlock: Fix makefile header list +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Matthieu Buffet + +[ Upstream commit e61462232a58bddd818fa6a913a9a2e76fd3634f ] + +Make all headers part of make's dependencies computations. +Otherwise, updating audit.h, common.h, scoped_base_variants.h, +scoped_common.h, scoped_multiple_domain_variants.h, or wrappers.h, +re-running make and running selftests could lead to testing stale headers. + +Fixes: 6a500b22971c ("selftests/landlock: Add tests for audit flags and domain IDs") +Fixes: fefcf0f7cf47 ("selftests/landlock: Test abstract UNIX socket scoping") +Fixes: 5147779d5e1b ("selftests/landlock: Add wrappers.h") +Signed-off-by: Matthieu Buffet +Link: https://lore.kernel.org/r/20251027011440.1838514-1-matthieu@buffet.re +Signed-off-by: Mickaël Salaün +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/landlock/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/landlock/Makefile b/tools/testing/selftests/landlock/Makefile +index a3f449914bf93..044b83bde16eb 100644 +--- a/tools/testing/selftests/landlock/Makefile ++++ b/tools/testing/selftests/landlock/Makefile +@@ -4,7 +4,7 @@ + + CFLAGS += -Wall -O2 $(KHDR_INCLUDES) + +-LOCAL_HDRS += common.h ++LOCAL_HDRS += $(wildcard *.h) + + src_test := $(wildcard *_test.c) + +-- +2.51.0 + diff --git a/queue-6.18/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch b/queue-6.18/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch new file mode 100644 index 0000000000..a0758ff86f --- /dev/null +++ b/queue-6.18/selftests-net-packetdrill-pass-send_omit_free-to-msg.patch @@ -0,0 +1,198 @@ +From 1d2b90bafa0f460793b10ecf588e01d527bba15c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 18:35:05 -0500 +Subject: selftests/net: packetdrill: pass send_omit_free to MSG_ZEROCOPY tests + +From: Willem de Bruijn + +[ Upstream commit c01a6e5b2e4f21d31cf725b9f3803cb0280b1b8d ] + +The --send_omit_free flag is needed for TCP zero copy tests, to ensure +that packetdrill doesn't free the send() buffer after the send() call. + +Fixes: 1e42f73fd3c2 ("selftests/net: packetdrill: import tcp/zerocopy") +Closes: https://lore.kernel.org/netdev/20251124071831.4cbbf412@kernel.org/ +Suggested-by: Neal Cardwell +Signed-off-by: Willem de Bruijn +Link: https://patch.msgid.link/20251125234029.1320984-1-willemdebruijn.kernel@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt | 4 ++++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt | 2 ++ + .../selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt | 3 +++ + .../net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt | 3 +++ + .../selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt | 3 +++ + .../net/packetdrill/tcp_zerocopy_fastopen-client.pkt | 2 ++ + .../net/packetdrill/tcp_zerocopy_fastopen-server.pkt | 2 ++ + .../selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt | 2 ++ + .../testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt | 2 ++ + 12 files changed, 29 insertions(+) + +diff --git a/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt b/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt +index b2b2cdf27e20f..454441e7ecff6 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_syscall_bad_arg_sendmsg-empty-iov.pkt +@@ -1,6 +1,10 @@ + // SPDX-License-Identifier: GPL-2.0 + // Test that we correctly skip zero-length IOVs. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` ++ + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_ZEROCOPY, [1], 4) = 0 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt +index a82c8899d36bf..0a0700afdaa38 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_basic.pkt +@@ -4,6 +4,8 @@ + // send a packet with MSG_ZEROCOPY and receive the notification ID + // repeat and verify IDs are consecutive + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt +index c01915e7f4a15..df91675d2991c 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_batch.pkt +@@ -3,6 +3,8 @@ + // + // send multiple packets, then read one range of all notifications. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt +index 6509882932e91..2963cfcb14dfd 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_client.pkt +@@ -1,6 +1,8 @@ + // SPDX-License-Identifier: GPL-2.0 + // Minimal client-side zerocopy test + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt +index 2cd78755cb2ac..ea0c2fa73c2d6 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_closed.pkt +@@ -7,6 +7,8 @@ + // First send on a closed socket and wait for (absent) notification. + // Then connect and send and verify that notification nr. is zero. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt +index 7671c20e01cf6..4df978a9b82e7 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_edge.pkt +@@ -7,6 +7,9 @@ + // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR + // is correctly fired only once, when EPOLLET is set. send another packet with + // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt +index fadc480fdb7fe..36b6edc4858c4 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_exclusive.pkt +@@ -8,6 +8,9 @@ + // fire two sends with MSG_ZEROCOPY and receive the acks. confirm that EPOLLERR + // is correctly fired only once, when EPOLLET is set. send another packet with + // MSG_ZEROCOPY. confirm that EPOLLERR is correctly fired again only once. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt +index 5bfa0d1d2f4a3..1bea6f3b4558d 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_epoll_oneshot.pkt +@@ -8,6 +8,9 @@ + // is correctly fired only once, when EPOLLONESHOT is set. send another packet + // with MSG_ZEROCOPY. confirm that EPOLLERR is not fired. Rearm the FD and + // confirm that EPOLLERR is correctly set. ++ ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt +index 4a73bbf469610..e27c21ff5d18d 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-client.pkt +@@ -8,6 +8,8 @@ + // one will have no data in the initial send. On return 0 the + // zerocopy notification counter is not incremented. Verify this too. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + // Send a FastOpen request, no cookie yet so no data in SYN +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt +index 36086c5877ce7..b1fa77c77dfa7 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_fastopen-server.pkt +@@ -4,6 +4,8 @@ + // send data with MSG_FASTOPEN | MSG_ZEROCOPY and verify that the + // kernel returns the notification ID. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh + ./set_sysctls.py /proc/sys/net/ipv4/tcp_fastopen=0x207` + +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt +index 672f817faca0d..2f5317d0a9fab 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_maxfrags.pkt +@@ -7,6 +7,8 @@ + // because each iovec element becomes a frag + // 3) the PSH bit is set on an skb when it runs out of fragments + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +diff --git a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt +index a9a1ac0aea4f4..9d5272c6b2079 100644 +--- a/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt ++++ b/tools/testing/selftests/net/packetdrill/tcp_zerocopy_small.pkt +@@ -4,6 +4,8 @@ + // verify that SO_EE_CODE_ZEROCOPY_COPIED is set on zerocopy + // packets of all sizes, including the smallest payload, 1B. + ++--send_omit_free // do not reuse send buffers with zerocopy ++ + `./defaults.sh` + + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series new file mode 100644 index 0000000000..d5aea428cc --- /dev/null +++ b/queue-6.18/series @@ -0,0 +1,536 @@ +smack-fix-bug-smack64transmute-set-on-non-directory.patch +smack-deduplicate-does-access-rule-request-transmuta.patch +smack-deduplicate-xattr-setting-in-smack_inode_init_.patch +smack-always-instantiate-inode-in-smack_inode_init_s.patch +smack-fix-bug-invalid-label-of-unix-socket-file.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +smack-fix-bug-setting-task-label-silently-ignores-in.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +accel-amdxdna-fix-an-integer-overflow-in-aie2_query_.patch +accel-amdxdna-call-dma_buf_vmap_unlocked-for-importe.patch +accel-ivpu-ensure-rpm_runtime_put-in-case-of-engine-.patch +drm-panel-visionox-rm69299-fix-clock-frequency-for-s.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +accel-ivpu-rework-bind-unbind-of-imported-buffers.patch +accel-ivpu-fix-page-fault-in-ivpu_bo_unbind_all_bos_.patch +accel-ivpu-fix-dct-active-percent-format.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +bpf-cleanup-unused-func-args-in-rqspinlock-implement.patch +bpf-fix-sleepable-context-for-async-callbacks.patch +bpf-fix-handling-maps-with-no-btf-and-non-constant-o.patch +tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +perf-bpf_counter-fix-opening-of-any-1-cpu-events.patch +pinctrl-qcom-glymur-drop-unnecessary-platform-data-f.patch +pinctrl-qcom-glymur-fix-the-gpio-and-egpio-pin-funct.patch +ima-attach-creds_check-ima-hook-to-bprm_creds_from_f.patch +pinctrl-renesas-rzg2l-fix-pmc-restore.patch +clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch +clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch +drm-atmel-hlcdc-fix-atmel_xlcdc_plane_setup_scaler.patch +hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch +remoteproc-imx_rproc-fix-runtime-pm-cleanup-and-impr.patch +objtool-fix-standalone-hacks-jump_label.patch +objtool-fix-weak-symbol-detection.patch +accel-ivpu-fix-race-condition-when-mapping-dmabuf.patch +perf-parse-events-fix-legacy-cache-events-if-event-i.patch +gpu-nova-core-gsp-remove-useless-conversion.patch +gpu-nova-core-gsp-do-not-unwrap-sgentry.patch +wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch +wifi-ath11k-restore-register-window-after-global-res.patch +wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch +wifi-ath12k-fix-vht-mcs-assignment.patch +wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch +sched-fair-forfeit-vruntime-on-yield.patch +irqchip-bcm2712-mip-fix-of-node-reference-imbalance.patch +irqchip-bcm2712-mip-fix-section-mismatch.patch +irqchip-irq-bcm7038-l1-fix-section-mismatch.patch +irqchip-irq-bcm7120-l2-fix-section-mismatch.patch +irqchip-irq-brcmstb-l2-fix-section-mismatch.patch +irqchip-imx-mu-msi-fix-section-mismatch.patch +irqchip-renesas-rzg2l-fix-section-mismatch.patch +irqchip-starfive-jh8100-fix-section-mismatch.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +irqchip-drop-leftover-brackets.patch +irqchip-pass-platform-device-to-platform-drivers.patch +crypto-authenc-correctly-pass-einprogress-back-up-to.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +arm64-dts-qcom-ipq5424-correct-the-tf-a-reserved-mem.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +firmware-qcom-tzmem-fix-qcom_tzmem_policy-kernel-doc.patch +perf-parse-events-make-x-modifier-more-respectful-of.patch +crypto-aead-fix-reqsize-handling.patch +pci-sg2042-fix-a-reference-count-issue-in-sg2042_pci.patch +block-mq-deadline-introduce-dd_start_request.patch +block-mq-deadline-switch-back-to-a-single-dispatch-l.patch +bpf-do-not-let-bpf-test-infra-emit-invalid-gso-types.patch +arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch +arm64-dts-imx95-15x15-evk-add-fan-supply-property-fo.patch +perf-annotate-check-return-value-of-evsel__get_arch-.patch +arm64-dts-exynos-gs101-fix-clock-module-unit-reg-siz.patch +arm64-dts-exynos-gs101-fix-sysreg_apm-reg-property.patch +pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +tty-serial-imx-only-configure-the-wake-register-when.patch +clk-qcom-camcc-sm8550-specify-titan-gdsc-power-domai.patch +clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch +clk-qcom-rpmh-define-rpmh_ipa_clk-on-qcs615.patch +clk-qcom-gcc-sm8750-add-a-new-frequency-for-sdcc2-cl.patch +clk-qcom-gcc-glymur-update-the-halt-check-flags-for-.patch +clk-qcom-gcc-ipq5424-correct-the-icc_first_node_id.patch +clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch +clk-qcom-camcc-sm7150-fix-pll-config-of-pll2.patch +soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +wifi-ath11k-fix-vht-mcs-assignment.patch +wifi-ath11k-fix-peer-he-mcs-assignment.patch +s390-smp-fix-fallback-cpu-detection.patch +scsi-ufs-core-move-the-ufshcd_enable_intr-declaratio.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +tools-power-turbostat-regression-fix-uncore-mhz-prin.patch +wifi-ath12k-restore-register-window-after-global-res.patch +accel-amdxdna-fix-uninitialized-return-value.patch +ice-move-service-task-start-out-of-ice_init_pf.patch +ice-move-ice_init_interrupt_scheme-prior-ice_init_pf.patch +ice-ice_init_pf-destroy-mutexes-and-xarrays-on-memor.patch +ice-move-udp_tunnel_nic-and-misc-irq-setup-into-ice_.patch +ice-move-ice_init_pf-out-of-ice_init_dev.patch +ice-extract-ice_init_dev-from-ice_init.patch +ice-move-ice_deinit_dev-to-the-end-of-deinit-paths.patch +ice-remove-duplicate-call-to-ice_deinit_hw-on-error-.patch +leds-upboard-fix-module-alias.patch +pci-endpoint-pci-epf-test-fix-sleeping-function-bein.patch +arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +arm64-dts-qcom-x1e80100-fix-compile-warnings-for-usb.patch +arm64-dts-qcom-x1e80100-add-missing-quirk-for-hs-onl.patch +arm64-dts-qcom-lemans-add-missing-quirk-for-hs-only-.patch +tools-nolibc-x86-fix-section-mismatch-caused-by-asm-.patch +arm64-dts-qcom-sdm845-starqltechn-remove-address-siz.patch +arm64-dts-qcom-sdm845-starqltechn-fix-max77705-inter.patch +arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch +arm64-dts-qcom-qcm6490-fairphone-fp5-add-supplies-to.patch +arm64-dts-qcom-sm8650-set-ufs-as-dma-coherent.patch +arm64-dts-qcom-sm8750-mtp-move-pcie-gpios-to-pciepor.patch +arm64-dts-qcom-qcm6490-shift-otter-add-missing-reser.patch +arm64-dts-qcom-x1-dell-thena-add-missing-pinctrl-for.patch +arm64-dts-qcom-x1-dell-thena-remove-dp-data-lanes.patch +arm64-dts-qcom-sc8280xp-fix-shifted-gpi-dma-channels.patch +arm64-dts-qcom-sdm845-starqltechn-fix-i2c-gpio-node-.patch +arm64-dts-qcom-sm8250-samsung-common-correct-reserve.patch +perf-hwmon_pmu-fix-uninitialized-variable-warning.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +arm64-dts-qcom-qcm2290-fix-camss-register-prop-order.patch +rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch +arm-dts-renesas-gose-remove-superfluous-port-propert.patch +arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch +drm-amdgpu-add-userq-object-va-track-helpers.patch +drm-amdgpu-userq-fix-sdma-and-compute-validation.patch +wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch +revert-mtd-rawnand-marvell-fix-layouts.patch +mtd-nand-relax-ecc-parameter-validation-check.patch +mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch +bpf-refactor-stack-map-trace-depth-calculation-into-.patch +bpf-fix-stackmap-overflow-check-in-__bpf_get_stackid.patch +perf-x86-intel-cstate-remove-pc3-support-from-lunarl.patch +task_work-fix-nmi-race-condition.patch +drm-rcar-du-dsi-fix-missing-parameter-in-rxsetr_.en-.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +accel-ivpu-remove-skip-of-dma-unmap-for-imported-buf.patch +media-ov02c10-fix-default-vertical-flip.patch +tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch +tools-nolibc-dirent-avoid-errno-in-readdir_r.patch +clk-qcom-gcc-qcs615-update-the-sdcc-clock-to-use-sha.patch +soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +drm-nova-select-nova_core.patch +accel-ivpu-fix-race-condition-when-unbinding-bos.patch +pidfs-add-missing-pidfd_info_size_ver1.patch +pidfs-add-missing-build_bug_on-assert-on-struct-pidf.patch +arm64-dts-ti-k3-j784s4-fix-i2c-pinmux-pull-configura.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +random-use-offstack-cpumask-when-necessary.patch +docs-kdoc-fix-duplicate-section-warning-message.patch +wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch +wifi-ath12k-fix-reusing-m3-memory.patch +wifi-ath12k-fix-error-handling-in-creating-hardware-.patch +wifi-ath12k-enforce-vdev-limit-in-ath12k_mac_vdev_cr.patch +wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch +interconnect-qcom-msm8996-add-missing-link-to-slave_.patch +arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch +accel-amdxdna-fix-incorrect-command-state-for-timed-.patch +interconnect-debugfs-fix-incorrect-error-handling-fo.patch +arm64-dts-renesas-sparrow-hawk-fix-full-size-dp-conn.patch +cgroup-add-cgroup-namespace-to-tree-after-owner-is-s.patch +drm-imagination-fix-reference-to-devm_platform_get_a.patch +perf-lock-contention-load-kernel-map-before-lookup.patch +perf-record-skip-synthesize-event-when-open-evsel-fa.patch +clk-qcom-tcsrcc-glymur-update-register-offsets-for-c.patch +timers-migration-convert-while-loops-to-use-for.patch +timers-migration-remove-locking-on-group-connection.patch +timers-migration-fix-imbalanced-numa-trees.patch +power-supply-rt5033_charger-fix-device-node-referenc.patch +power-supply-cw2015-check-devm_delayed_work_autocanc.patch +power-supply-max17040-check-iio_read_channel_process.patch +power-supply-rt9467-return-error-on-failure-in-rt946.patch +power-supply-rt9467-prevent-using-uninitialized-loca.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-qcom_battmgr-clamp-charge-control-thres.patch +power-supply-qcom_battmgr-support-disabling-charge-c.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +scsi-target-fix-lun-device-r-w-and-total-command-sta.patch +fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch +drm-panthor-handle-errors-returned-by-drm_sched_enti.patch +drm-panthor-fix-group_free_queue-for-partially-initi.patch +drm-panthor-fix-uaf-race-between-device-unplug-and-f.patch +drm-panthor-fix-race-with-suspend-during-unplug.patch +drm-panthor-fix-uaf-on-kernel-bo-va-nodes.patch +firmware-ti_sci-set-io-isolation-only-if-the-firmwar.patch +ns-add-ns_common_init.patch +ns-initialize-ns_list_node-for-initial-namespaces.patch +iommu-amd-fix-potential-out-of-bounds-read-in-iommu_.patch +cleanup-fix-scoped_class.patch +drm-xe-enforce-correct-user-fence-signaling-order-us.patch +spi-tegra210-quad-fix-timeout-handling.patch +libbpf-fix-parsing-of-multi-split-btf.patch +arm-dts-am33xx-add-missing-serial-console-speed.patch +arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch +arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch +arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch +entry-unwind-deferred-fix-unwind_reset_info-placemen.patch +arm64-tegra-add-pinctrl-definitions-for-pcie-ep-node.patch +coresight-etr-fix-etr-buffer-use-after-free-issue.patch +x86-boot-fix-page-table-access-in-5-level-to-4-level.patch +efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch +locktorture-fix-memory-leak-in-param_set_cpumask.patch +wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch +wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch +perf-annotate-fix-build-with-no_slang-1.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +accel-amdxdna-fix-dma_fence-leak-when-job-is-cancele.patch +hfs-fix-potential-use-after-free-in-hfs_correct_next.patch +arm64-dts-rockchip-fix-usb-type-c-host-mode-for-radx.patch +io_uring-use-write_once-for-user-shared-memory.patch +perf-x86-fix-null-event-access-and-potential-pebs-re.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +md-delete-mddev-kobj-before-deleting-gendisk-kobj.patch +md-fix-rcu-protection-in-md_wakeup_thread.patch +md-avoid-repeated-calls-to-del_gendisk.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +scsi-smartpqi-fix-device-resources-accessed-after-de.patch +staging-most-remove-broken-i2c-driver.patch +iio-imu-bmi270-fix-dev_err_probe-error-msg.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch +coresight-tmc-add-the-handle-of-the-event-to-the-pat.patch +ntfs3-init-run-lock-for-extend-inode.patch +drm-panthor-fix-potential-memleak-of-vma-structure.patch +scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch +md-delete-md_redundancy_group-when-array-is-becoming.patch +md-init-bioset-in-mddev_init.patch +cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch +powerpc-kdump-fix-size-calculation-for-hot-removed-m.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +net-export-netdev_get_by_index_lock.patch +io_uring-zcrx-call-netdev_queue_get_dma_dev-under-in.patch +fs-ntfs3-initialize-allocated-memory-before-use.patch +coresight-change-device-mode-to-atomic-type.patch +coresight-etm4x-always-set-tracer-s-device-mode-on-t.patch +coresight-etm3x-always-set-tracer-s-device-mode-on-t.patch +coresight-etm4x-correct-polling-idle-bit.patch +coresight-etm4x-add-context-synchronization-before-e.patch +coresight-etm4x-properly-control-filter-in-cpu-idle-.patch +perf-tools-fix-missing-feature-check-for-inherit-sam.patch +drm-tidss-remove-max_pclk_khz-and-min_pclk_khz-from-.patch +drm-tidss-move-oldi-mode-validation-to-oldi-bridge-m.patch +clk-renesas-r9a09g077-propagate-rate-changes-to-pare.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +ocfs2-use-correct-endian-in-ocfs2_dinode_has_extents.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-qla2xxx-clear-cmds-after-chip-reset.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +arm64-mm-allow-__create_pgd_mapping-to-propagate-pgt.patch +accel-amdxdna-clear-mailbox-interrupt-register-durin.patch +accel-amdxdna-fix-deadlock-between-context-destroy-a.patch +bpf-free-special-fields-when-update-lru_-percpu_hash.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +soc-renesas-r9a09g056-sys-populate-max_register.patch +soc-renesas-rz-sysc-populate-readable_reg-writeable_.patch +arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch-12419 +perf-vendor-metrics-s390-avoid-has_event-instruction.patch +crypto-iaa-fix-incorrect-return-value-in-save_iaa_wq.patch +s390-fpu-fix-false-positive-kmsan-report-in-fpu_vstl.patch +pwm-simplify-printf-to-emit-chip-npwm-in-debugfs-pwm.patch +pwm-use-u-to-printf-unsigned-int-pwm_chip-npwm-and-p.patch +arm64-dts-qcom-qrb2210-rb1-fix-uart3-wakeup-irq-stor.patch +drm-msm-dpu-drop-dpu_hw_dsc_destroy-prototype.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +soc-tegra-fuse-speedo-tegra210-update-speedo-ids.patch +pci-prevent-resource-tree-corruption-when-bar-resize.patch +kbuild-don-t-enable-cc_can_link-if-the-dummy-program.patch +bpf-prevent-nesting-overflow-in-bpf_try_get_buffers.patch +bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch +mshv-fix-deposit-memory-in-mshv_root_hvcall.patch +mshv-fix-create-memory-region-overlap-check.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +watchdog-starfive-fix-resource-leak-in-probe-error-p.patch +iio-core-add-missing-mutex_destroy-in-iio_dev_releas.patch +iio-core-clean-up-device-correctly-on-iio_device_all.patch +fuse_ctl_add_conn-fix-nlink-breakage-in-case-of-earl.patch +tracefs-fix-a-leak-in-eventfs_create_events_dir.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +arm64-dts-imx95-tqma9596sa-fix-tpm5-pinctrl-node-nam.patch +arm64-dts-imx95-tqma9596sa-reduce-maximum-flexspi-fr.patch +block-blk-throttle-fix-throttle-slice-time-for-ssds.patch +drm-msm-fix-null-pointer-dereference-in-crashstate_g.patch +drm-msm-fix-missing-null-check-after-kcalloc-in-cras.patch +drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch +pci-stm32-fix-ltssm-ep-race-with-start-link.patch +pci-stm32-fix-ep-page_size-alignment.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +net-phy-add-helper-for-fixing-rgmii-phy-mode-based-o.patch +net-stmmac-dwmac-sophgo-add-phy-interface-filter.patch +bpf-fix-invalid-prog-stats-access-when-update_effect.patch +powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +net-stmmac-fix-vlan-0-deletion-in-vlan_del_hw_rx_flt.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +drm-msm-a6xx-flush-lrz-cache-before-pt-switch.patch +drm-msm-a6xx-fix-the-gemnoc-workaround.patch +drm-msm-a6xx-improve-mx-rail-fallback-in-rpmh-vote-i.patch +spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch +ipv6-clear-ra-flags-when-adding-a-static-route.patch +perf-arm_spe-fix-memset-subclass-in-operation.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +scsi-ufs-rockchip-reset-controller-on-pre_change-of-.patch +scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch +net-phy-realtek-create-rtl8211f_config_rgmii_delay.patch +iommu-vt-d-set-intel_iommu_floppy_wa-depend-on-blk_d.patch +iommu-vt-d-fix-unused-invalidation-hint-in-qi_desc_i.patch +wifi-mac80211-fix-cmac-functions-not-handling-errors.patch +tools-rtla-fix-unassigned-nr_cpus.patch +tools-rtla-fix-on-threshold-always-triggering.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +of-fdt-consolidate-duplicate-code-into-helper-functi.patch +of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch +of-fdt-fix-the-len-check-in-early_init_dt_check_for_.patch-7312 +of-fdt-fix-incorrect-use-of-dt_root_addr_cells-in-ea.patch +leds-rgb-leds-qcom-lpg-don-t-enable-triled-when-conf.patch +phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch +phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch +phy-rockchip-naneng-combphy-fix-pcie-l1ss-support-rk.patch-10421 +phy-freescale-initialize-priv-lock.patch +phy-rockchip-samsung-hdptx-fix-reported-clock-rate-i.patch +phy-rockchip-samsung-hdptx-reduce-ropll-loop-bandwid.patch +phy-rockchip-samsung-hdptx-prevent-inter-pair-skew-f.patch +asoc-sdca-fix-missing-dash-in-hide-disco-property.patch +selftests-bpf-use-assert_strneq-to-factor-in-long-sl.patch +net-phy-adin1100-fix-software-power-down-ready-condi.patch +cpuset-treat-cpusets-in-attaching-as-populated.patch +clk-spacemit-set-clk_hw_onecell_data-num-before-usin.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ras-report-all-arm-processor-cper-information-to-use.patch +rtla-tests-extend-action-tests-to-5s.patch +rtla-tests-fix-osnoise-test-calling-timerlat.patch +rtla-fix-a-overriding-t-argument.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +regulator-pca9450-fix-error-code-in-probe.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +selftests-bpf-update-test_tag-to-use-sha256.patch +bpf-properly-verify-tail-call-behavior.patch +crypto-starfive-correctly-handle-return-of-sg_nents_.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +pm-devfreq-hisi-fix-potential-uaf-in-opp-handling.patch +risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch +erofs-correct-fsdax-detection.patch +erofs-limit-the-level-of-fs-stacking-for-file-backed.patch +rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch +rdma-bnxt_re-pass-correct-flag-for-dma-mr-creation.patch +crypto-ahash-fix-crypto_ahash_import-with-partial-bl.patch +crypto-ahash-zero-positive-err-value-in-ahash_update.patch +asoc-tas2781-correct-the-wrong-chip-id-for-reset-var.patch +asoc-tas2781-correct-the-wrong-period.patch +wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch +wifi-mt76-mt7996-remove-unnecessary-link_id-checks-i.patch +wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch +wifi-mt76-mt7996-remove-useless-check-in-mt7996_msdu.patch +revert-wifi-mt76-mt792x-improve-monitor-interface-ha.patch +wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch +wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch +wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch +wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch +wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch +wifi-mt76-mt7996-fix-mld-group-index-assignment.patch +wifi-mt76-mt7996-fix-mlo-set-key-and-group-key-issue.patch +wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch +wifi-mt76-mt7996-fix-emi-rings-for-rro.patch +wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch +wifi-mt76-move-mt76_abort_scan-out-of-mt76_reset_dev.patch +wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch +wifi-mt76-mt7996-skip-ieee80211_iter_keys-on-scannin.patch +wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +iommu-arm-smmu-v3-fix-error-check-in-arm_smmu_alloc_.patch +bpftool-allow-bpftool-to-build-with-openssl-3.patch +selftests-bpf-allow-selftests-to-build-with-older-xx.patch +btrfs-fix-double-free-of-qgroup-record-after-failure.patch +btrfs-fix-racy-bitfield-write-in-btrfs_clear_space_i.patch +btrfs-make-sure-extent-and-csum-paths-are-always-rel.patch +btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch +um-don-t-rename-vmap-to-kernel_vmap.patch +iomap-always-run-error-completions-in-user-context.patch +iomap-allocate-s_dio_done_wq-for-async-reads-as-well.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +rdma-irdma-add-a-missing-kfree-of-struct-irdma_pci_f.patch +rdma-irdma-fix-sigbus-in-aeq-destroy.patch +rdma-irdma-add-missing-mutex-destroy.patch +rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch +rdma-irdma-do-not-set-ibk_local_dma_lkey-for-gen3.patch +rdma-irdma-remove-doorbell-elision-logic.patch +rdma-irdma-fix-srq-shadow-area-address-initializatio.patch +arm64-dts-amlogic-meson-g12b-fix-l2-cache-reference-.patch +drm-panthor-avoid-adding-of-kernel-bos-to-extobj-lis.patch +clocksource-drivers-ralink-fix-resource-leaks-in-ini.patch +clocksource-drivers-stm-fix-double-deregistration-on.patch +clocksource-drivers-arm_arch_timer_mmio-prevent-driv.patch +clocksource-drivers-nxp-pit-prevent-driver-unbind.patch +clocksource-drivers-nxp-stm-fix-section-mismatches.patch +clocksource-drivers-nxp-stm-prevent-driver-unbind.patch +asoc-nau8325-use-simple-i2c-probe-function.patch +asoc-nau8325-add-missing-build-config.patch +gfs2-prevent-recursive-memory-reclaim.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +firmware_loader-make-rust_fw_loader_abstractions-sel.patch +greybus-gb-beagleplay-fix-timeout-handling-in-bootlo.patch +fs-refactor-file-timestamp-update-logic.patch +fs-lift-the-fmode_nocmtime-check-into-file_update_ti.patch +misc-rp1-fix-an-error-handling-path-in-rp1_probe.patch +kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +drm-amdkfd-assign-aid-to-uuid-in-topology-for-spx-mo.patch +hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ublk-prevent-invalid-access-with-debug.patch +selftests-landlock-fix-makefile-header-list.patch +bpf-fix-exclusive-map-memory-leak.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +selftests-net-packetdrill-pass-send_omit_free-to-msg.patch +of-skip-devicetree-kunit-tests-when-riscv-acpi-doesn.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-kernel-doc-for-mapping-free_coherent-func.patch +virtio-fix-typo-in-virtio_device_ready-comment.patch +virtio-fix-whitespace-in-virtio_config_ops.patch +virtio-fix-grammar-in-virtio_queue_info-docs.patch +virtio-fix-grammar-in-virtio_map_ops-docs.patch +virtio-standardize-returns-documentation-style.patch +virtio-fix-virtqueue_set_affinity-docs.patch +virtio-fix-map-ops-comment.patch +vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch +vhost-fix-kthread-worker-cgroup-failure-handling.patch +vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch +virtio-clean-up-features-qword-dword-terms.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch +soc-samsung-exynos-pmu-fix-structure-initialization.patch +arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch +arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +arm64-dts-mediatek-mt8195-fix-address-range-for-jpeg.patch +reinstate-resource-avoid-unnecessary-lookups-in-find.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +iavf-implement-settime64-with-eopnotsupp.patch +net-vxlan-prevent-null-deref-in-vxlan_xmit_one.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch +spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch +arm64-pageattr-propagate-return-value-from-__change_.patch +vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch +landlock-fix-handling-of-disconnected-directories.patch +net-phy-aquantia-check-for-nvmem-deferral.patch +selftests-bonding-add-delay-before-each-xvlan_over_b.patch +net-netpoll-initialize-work-queue-before-error-check.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +rqspinlock-enclose-lock-unlock-within-lock-entry-acq.patch +rqspinlock-use-trylock-fallback-when-per-cpu-rqnode-.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch +clk-keystone-fix-compile-testing.patch +smb-smbdirect-introduce-smbdirect_debug_err_ptr-help.patch +smb-smbdirect-introduce-smbdirect_check_status_-warn.patch +smb-server-relax-warn_on_once-smbdirect_socket_-chec.patch +smb-client-relax-warn_on_once-smbdirect_socket_-chec.patch +um-disable-kasan_inline-when-static_link-is-selected.patch +net-dsa-b53-fix-vlan_id_idx-write-size-for-bcm5325-6.patch +net-dsa-b53-fix-extracting-vid-from-entry-for-bcm532.patch +net-dsa-b53-b53_arl_read-25-use-the-entry-for-compar.patch +net-dsa-b53-move-reading-arl-entries-into-their-own-.patch +net-dsa-b53-move-writing-arl-entries-into-their-own-.patch +net-dsa-b53-provide-accessors-for-accessing-arl_srch.patch +net-dsa-b53-split-reading-search-entry-into-their-ow.patch +net-dsa-b53-move-arl-entry-functions-into-ops-struct.patch +net-dsa-b53-add-support-for-5389-5397-5398-arl-entry.patch +net-dsa-b53-use-same-arl-search-result-offset-for-bc.patch +net-dsa-b53-fix-cpu-port-unicast-arl-entries-for-bcm.patch +net-dsa-b53-add-support-for-bcm63xx-arl-entry-format.patch +net-dsa-b53-fix-bcm5325-65-arl-entry-multicast-port-.patch +net-dsa-b53-fix-bcm5325-65-arl-entry-vids.patch +net-hsr-create-an-api-to-get-hsr-port-type.patch +net-dsa-xrs700x-reject-unsupported-hsr-configuration.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-jitdump-add-sym-str-tables-to-build-id-generati.patch +exfat-fix-refcount-leak-in-exfat_find.patch +exfat-fix-divide-by-zero-in-exfat_allocate_bitmap.patch +perf-tools-mark-split-kallsyms-dsos-as-loaded.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +perf-kvm-fix-debug-assertion.patch +perf-hist-in-init-ensure-mem_info-is-put-on-error-pa.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +perf-stat-allow-no-events-to-open-if-this-is-a-null-.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch +9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch +sched-fair-fix-unfairness-caused-by-stalled-tg_load_.patch +sched-core-fix-psi_dequeue-for-proxy-execution.patch diff --git a/queue-6.18/smack-always-instantiate-inode-in-smack_inode_init_s.patch b/queue-6.18/smack-always-instantiate-inode-in-smack_inode_init_s.patch new file mode 100644 index 0000000000..2e4e64ddf0 --- /dev/null +++ b/queue-6.18/smack-always-instantiate-inode-in-smack_inode_init_s.patch @@ -0,0 +1,70 @@ +From 5eceac56e270c0b659276b58034c228ca17e1f8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:31 +0300 +Subject: smack: always "instantiate" inode in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 69204f6cdb90f56b7ca27966d1080841108fc5de ] + +If memory allocation for the SMACK64TRANSMUTE +xattr value fails in smack_inode_init_security(), +the SMK_INODE_INSTANT flag is not set in +(struct inode_smack *issp)->smk_flags, +leaving the inode as not "instantiated". + +It does not matter if fs frees the inode +after failed smack_inode_init_security() call, +but there is no guarantee for this. + +To be safe, mark the inode as "instantiated", +even if allocation of xattr values fails. + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 9eefb5cfccba5..db2a9aa9f1a05 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1015,6 +1015,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); ++ int rc = 0; ++ int transflag = 0; + bool trans_cred; + bool trans_rule; + +@@ -1043,18 +1045,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_inode = dsp; + + if (S_ISDIR(inode->i_mode)) { +- issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ transflag = SMK_INODE_TRANSMUTE; + + if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_TRANSMUTE, + TRANS_TRUE, + TRANS_TRUE_SIZE + )) +- return -ENOMEM; ++ rc = -ENOMEM; + } + } + +- issp->smk_flags |= SMK_INODE_INSTANT; ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ if (rc) ++ return rc; + + return xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, +-- +2.51.0 + diff --git a/queue-6.18/smack-deduplicate-does-access-rule-request-transmuta.patch b/queue-6.18/smack-deduplicate-does-access-rule-request-transmuta.patch new file mode 100644 index 0000000000..aac798467b --- /dev/null +++ b/queue-6.18/smack-deduplicate-does-access-rule-request-transmuta.patch @@ -0,0 +1,145 @@ +From 9876b848482337cb6342d95c3479d8a3f9123607 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:28 +0300 +Subject: smack: deduplicate "does access rule request transmutation" + +From: Konstantin Andreev + +[ Upstream commit 635a01da8385fc00a144ec24684100bd1aa9db11 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 57 +++++++++++++++++++++----------------- + 1 file changed, 32 insertions(+), 25 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 39a4caeb6bc8e..a005f5afb8e0d 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -962,6 +962,24 @@ static int smack_inode_alloc_security(struct inode *inode) + return 0; + } + ++/** ++ * smk_rule_transmutes - does access rule for (subject,object) contain 't'? ++ * @subject: a pointer to the subject's Smack label entry ++ * @object: a pointer to the object's Smack label entry ++ */ ++static bool ++smk_rule_transmutes(struct smack_known *subject, ++ const struct smack_known *object) ++{ ++ int may; ++ ++ rcu_read_lock(); ++ may = smk_access_entry(subject->smk_known, object->smk_known, ++ &subject->smk_rules); ++ rcu_read_unlock(); ++ return (may > 0) && (may & MAY_TRANSMUTE); ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -977,23 +995,19 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct xattr *xattrs, int *xattr_count) + { + struct task_smack *tsp = smack_cred(current_cred()); +- struct inode_smack *issp = smack_inode(inode); +- struct smack_known *skp = smk_of_task(tsp); +- struct smack_known *isp = smk_of_inode(inode); ++ struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); + struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); +- int may; ++ bool trans_cred; ++ bool trans_rule; + + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. + */ +- if (tsp->smk_task != tsp->smk_transmuted) { +- rcu_read_lock(); +- may = smk_access_entry(skp->smk_known, dsp->smk_known, +- &skp->smk_rules); +- rcu_read_unlock(); +- } ++ trans_cred = (tsp->smk_task == tsp->smk_transmuted); ++ if (!trans_cred) ++ trans_rule = smk_rule_transmutes(smk_of_task(tsp), dsp); + + /* + * In addition to having smk_task equal to smk_transmuted, +@@ -1001,9 +1015,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * requests transmutation then by all means transmute. + * Mark the inode as changed. + */ +- if ((tsp->smk_task == tsp->smk_transmuted) || +- (may > 0 && ((may & MAY_TRANSMUTE) != 0) && +- smk_inode_transmutable(dir))) { ++ if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { + struct xattr *xattr_transmute; + + /* +@@ -1012,8 +1024,8 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * inode label was already set correctly in + * smack_inode_alloc_security(). + */ +- if (tsp->smk_task != tsp->smk_transmuted) +- isp = issp->smk_inode = dsp; ++ if (!trans_cred) ++ issp->smk_inode = dsp; + + if (S_ISDIR(inode->i_mode)) { + issp->smk_flags |= SMK_INODE_TRANSMUTE; +@@ -1035,11 +1047,13 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + issp->smk_flags |= SMK_INODE_INSTANT; + + if (xattr) { +- xattr->value = kstrdup(isp->smk_known, GFP_NOFS); ++ const char *inode_label = issp->smk_inode->smk_known; ++ ++ xattr->value = kstrdup(inode_label, GFP_NOFS); + if (!xattr->value) + return -ENOMEM; + +- xattr->value_len = strlen(isp->smk_known); ++ xattr->value_len = strlen(inode_label); + xattr->name = XATTR_SMACK_SUFFIX; + } + +@@ -4917,7 +4931,6 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + struct task_smack *otsp = smack_cred(old); + struct task_smack *ntsp = smack_cred(new); + struct inode_smack *isp; +- int may; + + /* + * Use the process credential unless all of +@@ -4931,18 +4944,12 @@ static int smack_dentry_create_files_as(struct dentry *dentry, int mode, + isp = smack_inode(d_inode(dentry->d_parent)); + + if (isp->smk_flags & SMK_INODE_TRANSMUTE) { +- rcu_read_lock(); +- may = smk_access_entry(otsp->smk_task->smk_known, +- isp->smk_inode->smk_known, +- &otsp->smk_task->smk_rules); +- rcu_read_unlock(); +- + /* + * If the directory is transmuting and the rule + * providing access is transmuting use the containing + * directory label instead of the process label. + */ +- if (may > 0 && (may & MAY_TRANSMUTE)) { ++ if (smk_rule_transmutes(otsp->smk_task, isp->smk_inode)) { + ntsp->smk_task = isp->smk_inode; + ntsp->smk_transmuted = ntsp->smk_task; + } +-- +2.51.0 + diff --git a/queue-6.18/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch b/queue-6.18/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch new file mode 100644 index 0000000000..811e35858d --- /dev/null +++ b/queue-6.18/smack-deduplicate-xattr-setting-in-smack_inode_init_.patch @@ -0,0 +1,113 @@ +From cdf3da1d39d66543b205f2be73b1735478d0a2da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:30 +0300 +Subject: smack: deduplicate xattr setting in smack_inode_init_security() + +From: Konstantin Andreev + +[ Upstream commit 8e5d9f916a9678e2dcbed2289b87efd453e4e052 ] + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Stable-dep-of: 78fc6a94be25 ("smack: fix bug: invalid label of unix socket file") +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 56 ++++++++++++++++++++------------------ + 1 file changed, 29 insertions(+), 27 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index a005f5afb8e0d..9eefb5cfccba5 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -980,6 +980,24 @@ smk_rule_transmutes(struct smack_known *subject, + return (may > 0) && (may & MAY_TRANSMUTE); + } + ++static int ++xattr_dupval(struct xattr *xattrs, int *xattr_count, ++ const char *name, const void *value, unsigned int vallen) ++{ ++ struct xattr * const xattr = lsm_get_xattr_slot(xattrs, xattr_count); ++ ++ if (!xattr) ++ return 0; ++ ++ xattr->value = kmemdup(value, vallen, GFP_NOFS); ++ if (!xattr->value) ++ return -ENOMEM; ++ ++ xattr->value_len = vallen; ++ xattr->name = name; ++ return 0; ++} ++ + /** + * smack_inode_init_security - copy out the smack from an inode + * @inode: the newly created inode +@@ -997,7 +1015,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + struct task_smack *tsp = smack_cred(current_cred()); + struct inode_smack * const issp = smack_inode(inode); + struct smack_known *dsp = smk_of_inode(dir); +- struct xattr *xattr = lsm_get_xattr_slot(xattrs, xattr_count); + bool trans_cred; + bool trans_rule; + +@@ -1016,8 +1033,6 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + * Mark the inode as changed. + */ + if (trans_cred || (trans_rule && smk_inode_transmutable(dir))) { +- struct xattr *xattr_transmute; +- + /* + * The caller of smack_dentry_create_files_as() + * should have overridden the current cred, so the +@@ -1029,35 +1044,22 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + + if (S_ISDIR(inode->i_mode)) { + issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; +- } ++ ++ if (xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_TRANSMUTE, ++ TRANS_TRUE, ++ TRANS_TRUE_SIZE ++ )) ++ return -ENOMEM; + } + } + + issp->smk_flags |= SMK_INODE_INSTANT; + +- if (xattr) { +- const char *inode_label = issp->smk_inode->smk_known; +- +- xattr->value = kstrdup(inode_label, GFP_NOFS); +- if (!xattr->value) +- return -ENOMEM; +- +- xattr->value_len = strlen(inode_label); +- xattr->name = XATTR_SMACK_SUFFIX; +- } +- +- return 0; ++ return xattr_dupval(xattrs, xattr_count, ++ XATTR_SMACK_SUFFIX, ++ issp->smk_inode->smk_known, ++ strlen(issp->smk_inode->smk_known)); + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/smack-fix-bug-invalid-label-of-unix-socket-file.patch b/queue-6.18/smack-fix-bug-invalid-label-of-unix-socket-file.patch new file mode 100644 index 0000000000..a4a9511254 --- /dev/null +++ b/queue-6.18/smack-fix-bug-invalid-label-of-unix-socket-file.patch @@ -0,0 +1,200 @@ +From beee98291192f689c4f5f52a44f88f0e3867b34f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:32 +0300 +Subject: smack: fix bug: invalid label of unix socket file + +From: Konstantin Andreev + +[ Upstream commit 78fc6a94be252b27bb73e4926eed70b5e302a8e0 ] + +According to [1], the label of a UNIX domain socket (UDS) +file (i.e., the filesystem object representing the socket) +is not supposed to participate in Smack security. + +To achieve this, [1] labels UDS files with "*" +in smack_d_instantiate(). + +Before [2], smack_d_instantiate() was responsible +for initializing Smack security for all inodes, +except ones under /proc + +[2] imposed the sole responsibility for initializing +inode security for newly created filesystem objects +on smack_inode_init_security(). + +However, smack_inode_init_security() lacks some logic +present in smack_d_instantiate(). +In particular, it does not label UDS files with "*". + +This patch adds the missing labeling of UDS files +with "*" to smack_inode_init_security(). + +Labeling UDS files with "*" in smack_d_instantiate() +still works for stale UDS files that already exist on +disk. Stale UDS files are useless, but I keep labeling +them for consistency and maybe to make easier for user +to delete them. + +Compared to [1], this version introduces the following +improvements: + + * UDS file label is held inside inode only + and not saved to xattrs. + + * relabeling UDS files (setxattr, removexattr, etc.) + is blocked. + +[1] 2010-11-24 Casey Schaufler +commit b4e0d5f0791b ("Smack: UDS revision") + +[2] 2023-11-16 roberto.sassu +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 5 +++ + security/smack/smack_lsm.c | 58 +++++++++++++++++++------ + 2 files changed, 49 insertions(+), 14 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 6d44f4fdbf59f..1b554b5bf98e6 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -696,6 +696,11 @@ sockets. + A privileged program may set this to match the label of another + task with which it hopes to communicate. + ++UNIX domain socket (UDS) with a BSD address functions both as a file in a ++filesystem and as a socket. As a file, it carries the SMACK64 attribute. This ++attribute is not involved in Smack security enforcement and is immutably ++assigned the label "*". ++ + Smack Netlabel Exceptions + ~~~~~~~~~~~~~~~~~~~~~~~~~ + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index db2a9aa9f1a05..d16453801a79e 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1020,6 +1020,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + bool trans_cred; + bool trans_rule; + ++ /* ++ * UNIX domain sockets use lower level socket data. Let ++ * UDS inode have fixed * label to keep smack_inode_permission() calm ++ * when called from unix_find_bsd() ++ */ ++ if (S_ISSOCK(inode->i_mode)) { ++ /* forced label, no need to save to xattrs */ ++ issp->smk_inode = &smack_known_star; ++ goto instant_inode; ++ } + /* + * If equal, transmuting already occurred in + * smack_dentry_create_files_as(). No need to check again. +@@ -1056,14 +1066,16 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + } + } + +- issp->smk_flags |= (SMK_INODE_INSTANT | transflag); +- if (rc) +- return rc; +- +- return xattr_dupval(xattrs, xattr_count, ++ if (rc == 0) ++ if (xattr_dupval(xattrs, xattr_count, + XATTR_SMACK_SUFFIX, + issp->smk_inode->smk_known, +- strlen(issp->smk_inode->smk_known)); ++ strlen(issp->smk_inode->smk_known) ++ )) ++ rc = -ENOMEM; ++instant_inode: ++ issp->smk_flags |= (SMK_INODE_INSTANT | transflag); ++ return rc; + } + + /** +@@ -1337,13 +1349,23 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + int check_import = 0; + int check_star = 0; + int rc = 0; ++ umode_t const i_mode = d_backing_inode(dentry)->i_mode; + + /* + * Check label validity here so import won't fail in post_setxattr + */ +- if (strcmp(name, XATTR_NAME_SMACK) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || +- strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { ++ if (strcmp(name, XATTR_NAME_SMACK) == 0) { ++ /* ++ * UDS inode has fixed label ++ */ ++ if (S_ISSOCK(i_mode)) { ++ rc = -EINVAL; ++ } else { ++ check_priv = 1; ++ check_import = 1; ++ } ++ } else if (strcmp(name, XATTR_NAME_SMACKIPIN) == 0 || ++ strcmp(name, XATTR_NAME_SMACKIPOUT) == 0) { + check_priv = 1; + check_import = 1; + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0 || +@@ -1353,7 +1375,7 @@ static int smack_inode_setxattr(struct mnt_idmap *idmap, + check_star = 1; + } else if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { + check_priv = 1; +- if (!S_ISDIR(d_backing_inode(dentry)->i_mode) || ++ if (!S_ISDIR(i_mode) || + size != TRANS_TRUE_SIZE || + strncmp(value, TRANS_TRUE, TRANS_TRUE_SIZE) != 0) + rc = -EINVAL; +@@ -1484,12 +1506,15 @@ static int smack_inode_removexattr(struct mnt_idmap *idmap, + * Don't do anything special for these. + * XATTR_NAME_SMACKIPIN + * XATTR_NAME_SMACKIPOUT ++ * XATTR_NAME_SMACK if S_ISSOCK (UDS inode has fixed label) + */ + if (strcmp(name, XATTR_NAME_SMACK) == 0) { +- struct super_block *sbp = dentry->d_sb; +- struct superblock_smack *sbsp = smack_superblock(sbp); ++ if (!S_ISSOCK(d_backing_inode(dentry)->i_mode)) { ++ struct super_block *sbp = dentry->d_sb; ++ struct superblock_smack *sbsp = smack_superblock(sbp); + +- isp->smk_inode = sbsp->smk_default; ++ isp->smk_inode = sbsp->smk_default; ++ } + } else if (strcmp(name, XATTR_NAME_SMACKEXEC) == 0) + isp->smk_task = NULL; + else if (strcmp(name, XATTR_NAME_SMACKMMAP) == 0) +@@ -3607,7 +3632,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + */ + + /* +- * UNIX domain sockets use lower level socket data. ++ * UDS inode has fixed label (*) + */ + if (S_ISSOCK(inode->i_mode)) { + final = &smack_known_star; +@@ -4872,6 +4897,11 @@ static int smack_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) + + static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) + { ++ /* ++ * UDS inode has fixed label. Ignore nfs label. ++ */ ++ if (S_ISSOCK(inode->i_mode)) ++ return 0; + return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, + ctxlen, 0); + } +-- +2.51.0 + diff --git a/queue-6.18/smack-fix-bug-setting-task-label-silently-ignores-in.patch b/queue-6.18/smack-fix-bug-setting-task-label-silently-ignores-in.patch new file mode 100644 index 0000000000..4765cf8022 --- /dev/null +++ b/queue-6.18/smack-fix-bug-setting-task-label-silently-ignores-in.patch @@ -0,0 +1,463 @@ +From 72d20cb96af4c4d5864fd53e4391c80aba297b16 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:17 +0300 +Subject: smack: fix bug: setting task label silently ignores input garbage + +From: Konstantin Andreev + +[ Upstream commit 674e2b24791cbe8fd5dc8a0aed4cb4404fcd2028 ] + +This command: + # echo foo/bar >/proc/$$/attr/smack/current + +gives the task a label 'foo' w/o indication +that label does not match input. +Setting the label with lsm_set_self_attr() syscall +behaves identically. + +This occures because: + +1) smk_parse_smack() is used to convert input to a label +2) smk_parse_smack() takes only that part from the + beginning of the input that looks like a label. +3) `/' is prohibited in labels, so only "foo" is taken. + +(2) is by design, because smk_parse_smack() is used +for parsing strings which are more than just a label. + +Silent failure is not a good thing, and there are two +indicators that this was not done intentionally: + + (size >= SMK_LONGLABEL) ~> invalid + +clause at the beginning of the do_setattr() and the +"Returns the length of the smack label" claim +in the do_setattr() description. + +So I fixed this by adding one tiny check: +the taken label length == input length. + +Since input length is now strictly controlled, +I changed the two ways of setting label + + smack_setselfattr(): lsm_set_self_attr() syscall + smack_setprocattr(): > /proc/.../current + +to accommodate the divergence in +what they understand by "input length": + + smack_setselfattr counts mandatory \0 into input length, + smack_setprocattr does not. + + smack_setprocattr allows various trailers after label + +Related changes: + +* fixed description for smk_parse_smack + +* allow unprivileged tasks validate label syntax. + +* extract smk_parse_label_len() from smk_parse_smack() + so parsing may be done w/o string allocation. + +* extract smk_import_valid_label() from smk_import_entry() + to avoid repeated parsing. + +* smk_parse_smack(): scan null-terminated strings + for no more than SMK_LONGLABEL(256) characters + +* smack_setselfattr(): require struct lsm_ctx . flags == 0 + to reserve them for future. + +Fixes: e114e473771c ("Smack: Simplified Mandatory Access Control Kernel") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + Documentation/admin-guide/LSM/Smack.rst | 11 ++- + security/smack/smack.h | 3 + + security/smack/smack_access.c | 93 ++++++++++++++----- + security/smack/smack_lsm.c | 115 +++++++++++++++--------- + 4 files changed, 156 insertions(+), 66 deletions(-) + +diff --git a/Documentation/admin-guide/LSM/Smack.rst b/Documentation/admin-guide/LSM/Smack.rst +index 1b554b5bf98e6..c5ed775f2d107 100644 +--- a/Documentation/admin-guide/LSM/Smack.rst ++++ b/Documentation/admin-guide/LSM/Smack.rst +@@ -601,10 +601,15 @@ specification. + Task Attribute + ~~~~~~~~~~~~~~ + +-The Smack label of a process can be read from /proc//attr/current. A +-process can read its own Smack label from /proc/self/attr/current. A ++The Smack label of a process can be read from ``/proc//attr/current``. A ++process can read its own Smack label from ``/proc/self/attr/current``. A + privileged process can change its own Smack label by writing to +-/proc/self/attr/current but not the label of another process. ++``/proc/self/attr/current`` but not the label of another process. ++ ++Format of writing is : only the label or the label followed by one of the ++3 trailers: ``\n`` (by common agreement for ``/proc/...`` interfaces), ++``\0`` (because some applications incorrectly include it), ++``\n\0`` (because we think some applications may incorrectly include it). + + File Attribute + ~~~~~~~~~~~~~~ +diff --git a/security/smack/smack.h b/security/smack/smack.h +index bf6a6ed3946ce..759343a6bbaeb 100644 +--- a/security/smack/smack.h ++++ b/security/smack/smack.h +@@ -286,9 +286,12 @@ int smk_tskacc(struct task_smack *, struct smack_known *, + int smk_curacc(struct smack_known *, u32, struct smk_audit_info *); + int smack_str_from_perm(char *string, int access); + struct smack_known *smack_from_secid(const u32); ++int smk_parse_label_len(const char *string, int len); + char *smk_parse_smack(const char *string, int len); + int smk_netlbl_mls(int, char *, struct netlbl_lsm_secattr *, int); + struct smack_known *smk_import_entry(const char *, int); ++struct smack_known *smk_import_valid_label(const char *label, int label_len, ++ gfp_t gfp); + void smk_insert_entry(struct smack_known *skp); + struct smack_known *smk_find_entry(const char *); + bool smack_privileged(int cap); +diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c +index 2e4a0cb22782b..a289cb6672bd4 100644 +--- a/security/smack/smack_access.c ++++ b/security/smack/smack_access.c +@@ -443,19 +443,19 @@ struct smack_known *smk_find_entry(const char *string) + } + + /** +- * smk_parse_smack - parse smack label from a text string +- * @string: a text string that might contain a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_parse_label_len - calculate the length of the starting segment ++ * in the string that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated + * +- * Returns a pointer to the clean label or an error code. ++ * Returns the length of the segment (0 < L < SMK_LONGLABEL) or an error code. + */ +-char *smk_parse_smack(const char *string, int len) ++int smk_parse_label_len(const char *string, int len) + { +- char *smack; + int i; + +- if (len <= 0) +- len = strlen(string) + 1; ++ if (len <= 0 || len > SMK_LONGLABEL) ++ len = SMK_LONGLABEL; + + /* + * Reserve a leading '-' as an indicator that +@@ -463,7 +463,7 @@ char *smk_parse_smack(const char *string, int len) + * including /smack/cipso and /smack/cipso2 + */ + if (string[0] == '-') +- return ERR_PTR(-EINVAL); ++ return -EINVAL; + + for (i = 0; i < len; i++) + if (string[i] > '~' || string[i] <= ' ' || string[i] == '/' || +@@ -471,6 +471,25 @@ char *smk_parse_smack(const char *string, int len) + break; + + if (i == 0 || i >= SMK_LONGLABEL) ++ return -EINVAL; ++ ++ return i; ++} ++ ++/** ++ * smk_parse_smack - copy the starting segment in the string ++ * that constitutes a valid smack label ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the copy of the label or an error code. ++ */ ++char *smk_parse_smack(const char *string, int len) ++{ ++ char *smack; ++ int i = smk_parse_label_len(string, len); ++ ++ if (i < 0) + return ERR_PTR(-EINVAL); + + smack = kstrndup(string, i, GFP_NOFS); +@@ -554,31 +573,25 @@ int smack_populate_secattr(struct smack_known *skp) + } + + /** +- * smk_import_entry - import a label, return the list entry +- * @string: a text string that might be a Smack label +- * @len: the maximum size, or zero if it is NULL terminated. ++ * smk_import_valid_allocated_label - import a label, return the list entry ++ * @smack: a text string that is a valid Smack label and may be kfree()ed. ++ * It is consumed: either becomes a part of the entry or kfree'ed. + * +- * Returns a pointer to the entry in the label list that +- * matches the passed string, adding it if necessary, +- * or an error code. ++ * Returns: see description of smk_import_entry() + */ +-struct smack_known *smk_import_entry(const char *string, int len) ++static struct smack_known * ++smk_import_allocated_label(char *smack, gfp_t gfp) + { + struct smack_known *skp; +- char *smack; + int rc; + +- smack = smk_parse_smack(string, len); +- if (IS_ERR(smack)) +- return ERR_CAST(smack); +- + mutex_lock(&smack_known_lock); + + skp = smk_find_entry(smack); + if (skp != NULL) + goto freeout; + +- skp = kzalloc(sizeof(*skp), GFP_NOFS); ++ skp = kzalloc(sizeof(*skp), gfp); + if (skp == NULL) { + skp = ERR_PTR(-ENOMEM); + goto freeout; +@@ -608,6 +621,42 @@ struct smack_known *smk_import_entry(const char *string, int len) + return skp; + } + ++/** ++ * smk_import_entry - import a label, return the list entry ++ * @string: a text string that might contain a Smack label at the beginning ++ * @len: the maximum size to look into, may be zero if string is null-terminated ++ * ++ * Returns a pointer to the entry in the label list that ++ * matches the passed string, adding it if necessary, ++ * or an error code. ++ */ ++struct smack_known *smk_import_entry(const char *string, int len) ++{ ++ char *smack = smk_parse_smack(string, len); ++ ++ if (IS_ERR(smack)) ++ return ERR_CAST(smack); ++ ++ return smk_import_allocated_label(smack, GFP_NOFS); ++} ++ ++/** ++ * smk_import_valid_label - import a label, return the list entry ++ * @label a text string that is a valid Smack label, not null-terminated ++ * ++ * Returns: see description of smk_import_entry() ++ */ ++struct smack_known * ++smk_import_valid_label(const char *label, int label_len, gfp_t gfp) ++{ ++ char *smack = kstrndup(label, label_len, gfp); ++ ++ if (!smack) ++ return ERR_PTR(-ENOMEM); ++ ++ return smk_import_allocated_label(smack, gfp); ++} ++ + /** + * smack_from_secid - find the Smack label associated with a secid + * @secid: an integer that might be associated with a Smack label +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index 07dbc4cd303a7..7fd8a60b8be90 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3710,7 +3710,7 @@ static void smack_d_instantiate(struct dentry *opt_dentry, struct inode *inode) + * @attr: which attribute to fetch + * @ctx: buffer to receive the result + * @size: available size in, actual size out +- * @flags: unused ++ * @flags: reserved, currently zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3771,57 +3771,52 @@ static int smack_getprocattr(struct task_struct *p, const char *name, char **val + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns zero on success or an error code + */ +-static int do_setattr(u64 attr, void *value, size_t size) ++static int do_setattr(unsigned int attr, void *value, size_t size) + { + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- char *labelstr; +- int rc = 0; +- +- if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) +- return -EPERM; ++ int label_len; + ++ /* ++ * let unprivileged user validate input, check permissions later ++ */ + if (value == NULL || size == 0 || size >= SMK_LONGLABEL) + return -EINVAL; + +- if (attr != LSM_ATTR_CURRENT) +- return -EOPNOTSUPP; +- +- labelstr = smk_parse_smack(value, size); +- if (IS_ERR(labelstr)) +- return PTR_ERR(labelstr); ++ label_len = smk_parse_label_len(value, size); ++ if (label_len < 0 || label_len != size) ++ return -EINVAL; + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (labelstr[1] == '\0' /* '@', '*' */) { +- const char c = labelstr[0]; ++ if (label_len == 1 /* '@', '*' */) { ++ const char c = *(const char *)value; + + if (c == *smack_known_web.smk_known || +- c == *smack_known_star.smk_known) { +- rc = -EPERM; +- goto free_labelstr; +- } ++ c == *smack_known_star.smk_known) ++ return -EPERM; + } + + if (!smack_privileged(CAP_MAC_ADMIN)) { + const struct smack_known_list_elem *sklep; +- list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) +- goto free_labelstr; +- rc = -EPERM; +- } ++ list_for_each_entry(sklep, &tsp->smk_relabel, list) { ++ const char *cp = sklep->smk_label->smk_known; + +-free_labelstr: +- kfree(labelstr); +- if (rc) ++ if (strlen(cp) == label_len && ++ strncmp(cp, value, label_len) == 0) ++ goto in_relabel; ++ } + return -EPERM; ++in_relabel: ++ ; ++ } + +- skp = smk_import_entry(value, size); ++ skp = smk_import_valid_label(value, label_len, GFP_KERNEL); + if (IS_ERR(skp)) + return PTR_ERR(skp); + +@@ -3837,7 +3832,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + smk_destroy_label_list(&tsp->smk_relabel); + + commit_creds(new); +- return size; ++ return 0; + } + + /** +@@ -3845,7 +3840,7 @@ static int do_setattr(u64 attr, void *value, size_t size) + * @attr: which attribute to set + * @ctx: buffer containing the data + * @size: size of @ctx +- * @flags: unused ++ * @flags: reserved, must be zero + * + * Fill the passed user space @ctx with the details of the requested + * attribute. +@@ -3855,12 +3850,26 @@ static int do_setattr(u64 attr, void *value, size_t size) + static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + u32 size, u32 flags) + { +- int rc; ++ if (attr != LSM_ATTR_CURRENT) ++ return -EOPNOTSUPP; + +- rc = do_setattr(attr, ctx->ctx, ctx->ctx_len); +- if (rc > 0) +- return 0; +- return rc; ++ if (ctx->flags) ++ return -EINVAL; ++ /* ++ * string must have \0 terminator, included in ctx->ctx ++ * (see description of struct lsm_ctx) ++ */ ++ if (ctx->ctx_len == 0) ++ return -EINVAL; ++ ++ if (ctx->ctx[ctx->ctx_len - 1] != '\0') ++ return -EINVAL; ++ /* ++ * other do_setattr() caller, smack_setprocattr(), ++ * does not count \0 into size, so ++ * decreasing length by 1 to accommodate the divergence. ++ */ ++ return do_setattr(attr, ctx->ctx, ctx->ctx_len - 1); + } + + /** +@@ -3872,15 +3881,39 @@ static int smack_setselfattr(unsigned int attr, struct lsm_ctx *ctx, + * Sets the Smack value of the task. Only setting self + * is permitted and only with privilege + * +- * Returns the length of the smack label or an error code ++ * Returns the size of the input value or an error code + */ + static int smack_setprocattr(const char *name, void *value, size_t size) + { +- int attr = lsm_name_to_attr(name); ++ size_t realsize = size; ++ unsigned int attr = lsm_name_to_attr(name); + +- if (attr != LSM_ATTR_UNDEF) +- return do_setattr(attr, value, size); +- return -EINVAL; ++ switch (attr) { ++ case LSM_ATTR_UNDEF: return -EINVAL; ++ default: return -EOPNOTSUPP; ++ case LSM_ATTR_CURRENT: ++ ; ++ } ++ ++ /* ++ * The value for the "current" attribute is the label ++ * followed by one of the 4 trailers: none, \0, \n, \n\0 ++ * ++ * I.e. following inputs are accepted as 3-characters long label "foo": ++ * ++ * "foo" (3 characters) ++ * "foo\0" (4 characters) ++ * "foo\n" (4 characters) ++ * "foo\n\0" (5 characters) ++ */ ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\0')) ++ --realsize; ++ ++ if (realsize && (((const char *)value)[realsize - 1] == '\n')) ++ --realsize; ++ ++ return do_setattr(attr, value, realsize) ? : size; + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/smack-fix-bug-smack64transmute-set-on-non-directory.patch b/queue-6.18/smack-fix-bug-smack64transmute-set-on-non-directory.patch new file mode 100644 index 0000000000..a1b343c484 --- /dev/null +++ b/queue-6.18/smack-fix-bug-smack64transmute-set-on-non-directory.patch @@ -0,0 +1,81 @@ +From 11212fe6ac44b549477118a1e7ac67d33ce1e8be Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 16 Jun 2025 04:07:29 +0300 +Subject: smack: fix bug: SMACK64TRANSMUTE set on non-directory + +From: Konstantin Andreev + +[ Upstream commit 195da3ff244deff119c3f5244b464b2236ea1725 ] + +When a new file system object is created +and the conditions for label transmutation are met, +the SMACK64TRANSMUTE extended attribute is set +on the object regardless of its type: +file, pipe, socket, symlink, or directory. + +However, +SMACK64TRANSMUTE may only be set on directories. + +This bug is a combined effect of the commits [1] and [2] +which both transfer functionality +from smack_d_instantiate() to smack_inode_init_security(), +but only in part. + +Commit [1] set blank SMACK64TRANSMUTE on improper object types. +Commit [2] set "TRUE" SMACK64TRANSMUTE on improper object types. + +[1] 2023-06-10, +Fixes: baed456a6a2f ("smack: Set the SMACK64TRANSMUTE xattr in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20230610075738.3273764-3-roberto.sassu@huaweicloud.com/ + +[2] 2023-11-16, +Fixes: e63d86b8b764 ("smack: Initialize the in-memory inode in smack_inode_init_security()") +Link: https://lore.kernel.org/linux-security-module/20231116090125.187209-5-roberto.sassu@huaweicloud.com/ + +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index af986587841d8..39a4caeb6bc8e 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -1015,18 +1015,20 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, + if (tsp->smk_task != tsp->smk_transmuted) + isp = issp->smk_inode = dsp; + +- issp->smk_flags |= SMK_INODE_TRANSMUTE; +- xattr_transmute = lsm_get_xattr_slot(xattrs, +- xattr_count); +- if (xattr_transmute) { +- xattr_transmute->value = kmemdup(TRANS_TRUE, +- TRANS_TRUE_SIZE, +- GFP_NOFS); +- if (!xattr_transmute->value) +- return -ENOMEM; +- +- xattr_transmute->value_len = TRANS_TRUE_SIZE; +- xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ if (S_ISDIR(inode->i_mode)) { ++ issp->smk_flags |= SMK_INODE_TRANSMUTE; ++ xattr_transmute = lsm_get_xattr_slot(xattrs, ++ xattr_count); ++ if (xattr_transmute) { ++ xattr_transmute->value = kmemdup(TRANS_TRUE, ++ TRANS_TRUE_SIZE, ++ GFP_NOFS); ++ if (!xattr_transmute->value) ++ return -ENOMEM; ++ ++ xattr_transmute->value_len = TRANS_TRUE_SIZE; ++ xattr_transmute->name = XATTR_SMACK_TRANSMUTE; ++ } + } + } + +-- +2.51.0 + diff --git a/queue-6.18/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-6.18/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..8b6180d1ab --- /dev/null +++ b/queue-6.18/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From 9d93ed0eac5f31fc9c1921836b7b0dd18f8f8763 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d16453801a79e..07dbc4cd303a7 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3778,8 +3778,8 @@ static int do_setattr(u64 attr, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3790,28 +3790,41 @@ static int do_setattr(u64 attr, void *value, size_t size) + if (attr != LSM_ATTR_CURRENT) + return -EOPNOTSUPP; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.18/smb-client-relax-warn_on_once-smbdirect_socket_-chec.patch b/queue-6.18/smb-client-relax-warn_on_once-smbdirect_socket_-chec.patch new file mode 100644 index 0000000000..12437d514c --- /dev/null +++ b/queue-6.18/smb-client-relax-warn_on_once-smbdirect_socket_-chec.patch @@ -0,0 +1,164 @@ +From fbafb7b7eb182c00c9afd74dca72343648800993 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 15:21:54 +0100 +Subject: smb: client: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in + recv_done() and smbd_conn_upcall() + +From: Stefan Metzmacher + +[ Upstream commit dc10cf1368af8cb816dcaa2502ba7d44fff20612 ] + +sc->first_error might already be set and sc->status +is thus unexpected, so this should avoid the WARN[_ON]_ONCE() +if sc->first_error is already set and have a usable error path. + +While there set sc->first_error as soon as possible. + +This is done based on a problem seen in similar places on +the server. And there it was already very useful in order +to find the problem when we have a meaningful WARN_ONCE() +that prints details about the connection. + +This is much more useful: + +[ 309.560973] expected[NEGOTIATE_NEEDED] != RDMA_CONNECT_RUNNING +first_error=0 local=192.168.0.200:445 remote=192.168.0.100:60445 +[ 309.561034] WARNING: CPU: 2 PID: 78 at transport_rdma.c:643 +recv_done+0x2fa/0x3d0 [ksmbd] + +than what we had before (only): + +[ 894.140316] WARNING: CPU: 1 PID: 116 at +fs/smb/server/transport_rdma.c:642 recv_done+0x308/0x360 [ksmbd] + +Fixes: 58dfba8a2d4e ("smb: client/smbdirect: replace SMBDIRECT_SOCKET_CONNECTING with more detailed states") +Cc: Steve French +Cc: Tom Talpey +Cc: Long Li +Cc: Namjae Jeon +Cc: Paulo Alcantara +Cc: linux-cifs@vger.kernel.org +Cc: samba-technical@lists.samba.org +Signed-off-by: Stefan Metzmacher +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/client/smbdirect.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +diff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c +index c6c428c2e08dd..788a0670c4a8d 100644 +--- a/fs/smb/client/smbdirect.c ++++ b/fs/smb/client/smbdirect.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#define __SMBDIRECT_SOCKET_DISCONNECT(__sc) smbd_disconnect_rdma_connection(__sc) + #include "../common/smbdirect/smbdirect_pdu.h" + #include "smbdirect.h" + #include "cifs_debug.h" +@@ -186,6 +187,9 @@ static void smbd_disconnect_rdma_work(struct work_struct *work) + struct smbdirect_socket *sc = + container_of(work, struct smbdirect_socket, disconnect_work); + ++ if (sc->first_error == 0) ++ sc->first_error = -ECONNABORTED; ++ + /* + * make sure this and other work is not queued again + * but here we don't block and avoid +@@ -197,9 +201,6 @@ static void smbd_disconnect_rdma_work(struct work_struct *work) + disable_work(&sc->idle.immediate_work); + disable_delayed_work(&sc->idle.timer_work); + +- if (sc->first_error == 0) +- sc->first_error = -ECONNABORTED; +- + switch (sc->status) { + case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED: + case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING: +@@ -242,6 +243,9 @@ static void smbd_disconnect_rdma_work(struct work_struct *work) + + static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc) + { ++ if (sc->first_error == 0) ++ sc->first_error = -ECONNABORTED; ++ + /* + * make sure other work (than disconnect_work) is + * not queued again but here we don't block and avoid +@@ -252,9 +256,6 @@ static void smbd_disconnect_rdma_connection(struct smbdirect_socket *sc) + disable_work(&sc->idle.immediate_work); + disable_delayed_work(&sc->idle.timer_work); + +- if (sc->first_error == 0) +- sc->first_error = -ECONNABORTED; +- + switch (sc->status) { + case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED: + case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED: +@@ -322,27 +323,27 @@ static int smbd_conn_upcall( + + switch (event->event) { + case RDMA_CM_EVENT_ADDR_RESOLVED: +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING); ++ if (SMBDIRECT_CHECK_STATUS_DISCONNECT(sc, SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING)) ++ break; + sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_NEEDED; + wake_up(&sc->status_wait); + break; + + case RDMA_CM_EVENT_ROUTE_RESOLVED: +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING); ++ if (SMBDIRECT_CHECK_STATUS_DISCONNECT(sc, SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING)) ++ break; + sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_NEEDED; + wake_up(&sc->status_wait); + break; + + case RDMA_CM_EVENT_ADDR_ERROR: + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ADDR_RUNNING); + sc->status = SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED; + smbd_disconnect_rdma_work(&sc->disconnect_work); + break; + + case RDMA_CM_EVENT_ROUTE_ERROR: + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RESOLVE_ROUTE_RUNNING); + sc->status = SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED; + smbd_disconnect_rdma_work(&sc->disconnect_work); + break; +@@ -428,7 +429,8 @@ static int smbd_conn_upcall( + min_t(u8, sp->responder_resources, + peer_responder_resources); + +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING); ++ if (SMBDIRECT_CHECK_STATUS_DISCONNECT(sc, SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING)) ++ break; + sc->status = SMBDIRECT_SOCKET_NEGOTIATE_NEEDED; + wake_up(&sc->status_wait); + break; +@@ -437,7 +439,6 @@ static int smbd_conn_upcall( + case RDMA_CM_EVENT_UNREACHABLE: + case RDMA_CM_EVENT_REJECTED: + log_rdma_event(ERR, "connecting failed event=%s\n", event_name); +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING); + sc->status = SMBDIRECT_SOCKET_RDMA_CONNECT_FAILED; + smbd_disconnect_rdma_work(&sc->disconnect_work); + break; +@@ -699,7 +700,8 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) + negotiate_done = + process_negotiation_response(response, wc->byte_len); + put_receive_buffer(sc, response); +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_NEGOTIATE_RUNNING); ++ if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_NEGOTIATE_RUNNING)) ++ negotiate_done = false; + if (!negotiate_done) { + sc->status = SMBDIRECT_SOCKET_NEGOTIATE_FAILED; + smbd_disconnect_rdma_connection(sc); +-- +2.51.0 + diff --git a/queue-6.18/smb-server-relax-warn_on_once-smbdirect_socket_-chec.patch b/queue-6.18/smb-server-relax-warn_on_once-smbdirect_socket_-chec.patch new file mode 100644 index 0000000000..31f4dd7cad --- /dev/null +++ b/queue-6.18/smb-server-relax-warn_on_once-smbdirect_socket_-chec.patch @@ -0,0 +1,271 @@ +From 31a9923c461aeb87bcc20d54669bda8e76b28dc9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 15:21:53 +0100 +Subject: smb: server: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in + recv_done() and smb_direct_cm_handler() + +From: Stefan Metzmacher + +[ Upstream commit 425c32750b48956a6e156b6a4609d281ee471359 ] + +Namjae reported the following: + +I have a simple file copy test with windows 11 client, and get the +following error message. + +[ 894.140312] ------------[ cut here ]------------ +[ 894.140316] WARNING: CPU: 1 PID: 116 at +fs/smb/server/transport_rdma.c:642 recv_done+0x308/0x360 [ksmbd] +[ 894.140335] Modules linked in: ksmbd cmac nls_utf8 nls_ucs2_utils +libarc4 nls_iso8859_1 snd_hda_codec_intelhdmi snd_hda_codec_hdmi +snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic +rpcrdma intel_rapl_msr rdma_ucm intel_rapl_common snd_hda_intel +ib_iser snd_hda_codec intel_uncore_frequency +intel_uncore_frequency_common snd_hda_core intel_tcc_cooling +x86_pkg_temp_thermal intel_powerclamp snd_intel_dspcfg libiscsi +snd_intel_sdw_acpi coretemp scsi_transport_iscsi snd_hwdep kvm_intel +i915 snd_pcm ib_umad rdma_cm snd_seq_midi ib_ipoib kvm +snd_seq_midi_event iw_cm snd_rawmidi ghash_clmulni_intel ib_cm +aesni_intel snd_seq mei_hdcp drm_buddy rapl snd_seq_device eeepc_wmi +asus_wmi snd_timer intel_cstate ttm snd drm_client_lib +drm_display_helper sparse_keymap soundcore platform_profile mxm_wmi +wmi_bmof joydev mei_me cec acpi_pad mei rc_core drm_kms_helper +input_leds i2c_algo_bit mac_hid sch_fq_codel msr parport_pc ppdev lp +nfsd parport auth_rpcgss binfmt_misc nfs_acl lockd grace drm sunrpc +ramoops efi_pstore +[ 894.140414] reed_solomon pstore_blk pstore_zone autofs4 btrfs +blake2b_generic xor raid6_pq mlx5_ib ib_uverbs ib_core hid_generic uas +usbhid hid r8169 i2c_i801 usb_storage i2c_mux i2c_smbus mlx5_core +realtek ahci mlxfw psample libahci video wmi [last unloaded: ksmbd] +[ 894.140442] CPU: 1 UID: 0 PID: 116 Comm: kworker/1:1H Tainted: G + W 6.18.0-rc5+ #1 PREEMPT(voluntary) +[ 894.140447] Tainted: [W]=WARN +[ 894.140448] Hardware name: System manufacturer System Product +Name/H110M-K, BIOS 3601 12/12/2017 +[ 894.140450] Workqueue: ib-comp-wq ib_cq_poll_work [ib_core] +[ 894.140476] RIP: 0010:recv_done+0x308/0x360 [ksmbd] +[ 894.140487] Code: 2e f2 ff ff 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc +cc cc cc 41 8b 55 10 49 8b 75 08 b9 02 00 00 00 e8 ed f4 f2 c3 e9 59 +fd ff ff <0f> 0b e9 02 ff ff ff 49 8b 74 24 28 49 8d 94 24 c8 00 00 00 +bf 00 +[ 894.140490] RSP: 0018:ffffa47ec03f3d78 EFLAGS: 00010293 +[ 894.140492] RAX: 0000000000000001 RBX: ffff8eb84c818000 RCX: 000000010002ba00 +[ 894.140494] RDX: 0000000037600001 RSI: 0000000000000083 RDI: ffff8eb92ec9ee40 +[ 894.140496] RBP: ffffa47ec03f3da0 R08: 0000000000000000 R09: 0000000000000010 +[ 894.140498] R10: ffff8eb801705680 R11: fefefefefefefeff R12: ffff8eb7454b8810 +[ 894.140499] R13: ffff8eb746deb988 R14: ffff8eb746deb980 R15: ffff8eb84c818000 +[ 894.140501] FS: 0000000000000000(0000) GS:ffff8eb9a7355000(0000) +knlGS:0000000000000000 +[ 894.140503] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 894.140505] CR2: 00002d9401d60018 CR3: 0000000010a40006 CR4: 00000000003726f0 +[ 894.140507] Call Trace: +[ 894.140509] +[ 894.140512] __ib_process_cq+0x8e/0x190 [ib_core] +[ 894.140530] ib_cq_poll_work+0x2f/0x90 [ib_core] +[ 894.140545] process_scheduled_works+0xd4/0x430 +[ 894.140554] worker_thread+0x12a/0x270 +[ 894.140558] kthread+0x10d/0x250 +[ 894.140564] ? __pfx_worker_thread+0x10/0x10 +[ 894.140567] ? __pfx_kthread+0x10/0x10 +[ 894.140571] ret_from_fork+0x11a/0x160 +[ 894.140574] ? __pfx_kthread+0x10/0x10 +[ 894.140577] ret_from_fork_asm+0x1a/0x30 +[ 894.140584] +[ 894.140585] ---[ end trace 0000000000000000 ]--- +[ 894.154363] ------------[ cut here ]------------ +[ 894.154367] WARNING: CPU: 3 PID: 5543 at +fs/smb/server/transport_rdma.c:1728 smb_direct_cm_handler+0x121/0x130 +[ksmbd] +[ 894.154384] Modules linked in: ksmbd cmac nls_utf8 nls_ucs2_utils +libarc4 nls_iso8859_1 snd_hda_codec_intelhdmi snd_hda_codec_hdmi +snd_hda_codec_alc882 snd_hda_codec_realtek_lib snd_hda_codec_generic +rpcrdma intel_rapl_msr rdma_ucm intel_rapl_common snd_hda_intel +ib_iser snd_hda_codec intel_uncore_frequency +intel_uncore_frequency_common snd_hda_core intel_tcc_cooling +x86_pkg_temp_thermal intel_powerclamp snd_intel_dspcfg libiscsi +snd_intel_sdw_acpi coretemp scsi_transport_iscsi snd_hwdep kvm_intel +i915 snd_pcm ib_umad rdma_cm snd_seq_midi ib_ipoib kvm +snd_seq_midi_event iw_cm snd_rawmidi ghash_clmulni_intel ib_cm +aesni_intel snd_seq mei_hdcp drm_buddy rapl snd_seq_device eeepc_wmi +asus_wmi snd_timer intel_cstate ttm snd drm_client_lib +drm_display_helper sparse_keymap soundcore platform_profile mxm_wmi +wmi_bmof joydev mei_me cec acpi_pad mei rc_core drm_kms_helper +input_leds i2c_algo_bit mac_hid sch_fq_codel msr parport_pc ppdev lp +nfsd parport auth_rpcgss binfmt_misc nfs_acl lockd grace drm sunrpc +ramoops efi_pstore +[ 894.154456] reed_solomon pstore_blk pstore_zone autofs4 btrfs +blake2b_generic xor raid6_pq mlx5_ib ib_uverbs ib_core hid_generic uas +usbhid hid r8169 i2c_i801 usb_storage i2c_mux i2c_smbus mlx5_core +realtek ahci mlxfw psample libahci video wmi [last unloaded: ksmbd] +[ 894.154483] CPU: 3 UID: 0 PID: 5543 Comm: kworker/3:6 Tainted: G + W 6.18.0-rc5+ #1 PREEMPT(voluntary) +[ 894.154487] Tainted: [W]=WARN +[ 894.154488] Hardware name: System manufacturer System Product +Name/H110M-K, BIOS 3601 12/12/2017 +[ 894.154490] Workqueue: ib_cm cm_work_handler [ib_cm] +[ 894.154499] RIP: 0010:smb_direct_cm_handler+0x121/0x130 [ksmbd] +[ 894.154507] Code: e7 e8 13 b1 ef ff 44 89 e1 4c 89 ee 48 c7 c7 80 +d7 59 c1 48 89 c2 e8 2e 4d ef c3 31 c0 5b 41 5c 41 5d 41 5e 5d c3 cc +cc cc cc <0f> 0b eb a5 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 90 +90 90 +[ 894.154510] RSP: 0018:ffffa47ec1b27c00 EFLAGS: 00010206 +[ 894.154512] RAX: ffffffffc1304e00 RBX: ffff8eb89ae50880 RCX: 0000000000000000 +[ 894.154514] RDX: ffff8eb730960000 RSI: ffffa47ec1b27c60 RDI: ffff8eb7454b9400 +[ 894.154515] RBP: ffffa47ec1b27c20 R08: 0000000000000002 R09: ffff8eb730b8c18b +[ 894.154517] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000009 +[ 894.154518] R13: ffff8eb7454b9400 R14: ffff8eb7454b8810 R15: ffff8eb815c43000 +[ 894.154520] FS: 0000000000000000(0000) GS:ffff8eb9a7455000(0000) +knlGS:0000000000000000 +[ 894.154522] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 894.154523] CR2: 00007fe1310e99d0 CR3: 0000000010a40005 CR4: 00000000003726f0 +[ 894.154525] Call Trace: +[ 894.154527] +[ 894.154530] cma_cm_event_handler+0x27/0xd0 [rdma_cm] +[ 894.154541] cma_ib_handler+0x99/0x2e0 [rdma_cm] +[ 894.154551] cm_process_work+0x28/0xf0 [ib_cm] +[ 894.154557] cm_queue_work_unlock+0x41/0xf0 [ib_cm] +[ 894.154563] cm_work_handler+0x2eb/0x25b0 [ib_cm] +[ 894.154568] ? pwq_activate_first_inactive+0x52/0x70 +[ 894.154572] ? pwq_dec_nr_in_flight+0x244/0x330 +[ 894.154575] process_scheduled_works+0xd4/0x430 +[ 894.154579] worker_thread+0x12a/0x270 +[ 894.154581] kthread+0x10d/0x250 +[ 894.154585] ? __pfx_worker_thread+0x10/0x10 +[ 894.154587] ? __pfx_kthread+0x10/0x10 +[ 894.154590] ret_from_fork+0x11a/0x160 +[ 894.154593] ? __pfx_kthread+0x10/0x10 +[ 894.154596] ret_from_fork_asm+0x1a/0x30 +[ 894.154602] +[ 894.154603] ---[ end trace 0000000000000000 ]--- +[ 894.154931] ksmbd: smb_direct: disconnected +[ 894.157278] ksmbd: smb_direct: disconnected + +I guess sc->first_error is already set and sc->status +is thus unexpected, so this should avoid the WARN[_ON]_ONCE() +if sc->first_error is already set and have a usable error path. + +While there set sc->first_error as soon as possible. + +v1 of this patch revealed the real problem with this message: + +[ 309.560973] expected[NEGOTIATE_NEEDED] != RDMA_CONNECT_RUNNING +first_error=0 local=192.168.0.200:445 remote=192.168.0.100:60445 +[ 309.561034] WARNING: CPU: 2 PID: 78 at transport_rdma.c:643 +recv_done+0x2fa/0x3d0 [ksmbd] + +Some drivers (at least mlx5_ib) might post a recv completion before +RDMA_CM_EVENT_ESTABLISHED, so we need to adjust our expectation in that +case. + +Fixes: e2d5e516c663 ("smb: server: only turn into SMBDIRECT_SOCKET_CONNECTED when negotiation is done") +Cc: Steve French +Cc: Tom Talpey +Cc: Long Li +Cc: Namjae Jeon +Cc: Paulo Alcantara +Cc: linux-cifs@vger.kernel.org +Cc: samba-technical@lists.samba.org +Signed-off-by: Stefan Metzmacher +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +--- + fs/smb/server/transport_rdma.c | 40 +++++++++++++++++++++++++++------- + 1 file changed, 32 insertions(+), 8 deletions(-) + +diff --git a/fs/smb/server/transport_rdma.c b/fs/smb/server/transport_rdma.c +index e2be9a4961546..4e7ab8d9314f6 100644 +--- a/fs/smb/server/transport_rdma.c ++++ b/fs/smb/server/transport_rdma.c +@@ -19,6 +19,8 @@ + #include + #include + ++#define __SMBDIRECT_SOCKET_DISCONNECT(__sc) smb_direct_disconnect_rdma_connection(__sc) ++ + #include "glob.h" + #include "connection.h" + #include "smb_common.h" +@@ -231,6 +233,9 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work) + struct smbdirect_socket *sc = + container_of(work, struct smbdirect_socket, disconnect_work); + ++ if (sc->first_error == 0) ++ sc->first_error = -ECONNABORTED; ++ + /* + * make sure this and other work is not queued again + * but here we don't block and avoid +@@ -241,9 +246,6 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work) + disable_delayed_work(&sc->idle.timer_work); + disable_work(&sc->idle.immediate_work); + +- if (sc->first_error == 0) +- sc->first_error = -ECONNABORTED; +- + switch (sc->status) { + case SMBDIRECT_SOCKET_NEGOTIATE_NEEDED: + case SMBDIRECT_SOCKET_NEGOTIATE_RUNNING: +@@ -287,6 +289,9 @@ static void smb_direct_disconnect_rdma_work(struct work_struct *work) + static void + smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc) + { ++ if (sc->first_error == 0) ++ sc->first_error = -ECONNABORTED; ++ + /* + * make sure other work (than disconnect_work) is + * not queued again but here we don't block and avoid +@@ -296,9 +301,6 @@ smb_direct_disconnect_rdma_connection(struct smbdirect_socket *sc) + disable_work(&sc->idle.immediate_work); + disable_delayed_work(&sc->idle.timer_work); + +- if (sc->first_error == 0) +- sc->first_error = -ECONNABORTED; +- + switch (sc->status) { + case SMBDIRECT_SOCKET_RESOLVE_ADDR_FAILED: + case SMBDIRECT_SOCKET_RESOLVE_ROUTE_FAILED: +@@ -639,7 +641,18 @@ static void recv_done(struct ib_cq *cq, struct ib_wc *wc) + return; + } + sc->recv_io.reassembly.full_packet_received = true; +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_NEGOTIATE_NEEDED); ++ /* ++ * Some drivers (at least mlx5_ib) might post a ++ * recv completion before RDMA_CM_EVENT_ESTABLISHED, ++ * we need to adjust our expectation in that case. ++ */ ++ if (!sc->first_error && sc->status == SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING) ++ sc->status = SMBDIRECT_SOCKET_NEGOTIATE_NEEDED; ++ if (SMBDIRECT_CHECK_STATUS_WARN(sc, SMBDIRECT_SOCKET_NEGOTIATE_NEEDED)) { ++ put_recvmsg(sc, recvmsg); ++ smb_direct_disconnect_rdma_connection(sc); ++ return; ++ } + sc->status = SMBDIRECT_SOCKET_NEGOTIATE_RUNNING; + enqueue_reassembly(sc, recvmsg, 0); + wake_up(&sc->status_wait); +@@ -1725,7 +1738,18 @@ static int smb_direct_cm_handler(struct rdma_cm_id *cm_id, + + switch (event->event) { + case RDMA_CM_EVENT_ESTABLISHED: { +- WARN_ON_ONCE(sc->status != SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING); ++ /* ++ * Some drivers (at least mlx5_ib) might post a ++ * recv completion before RDMA_CM_EVENT_ESTABLISHED, ++ * we need to adjust our expectation in that case. ++ * ++ * As we already started the negotiation, we just ++ * ignore RDMA_CM_EVENT_ESTABLISHED here. ++ */ ++ if (!sc->first_error && sc->status > SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING) ++ break; ++ if (SMBDIRECT_CHECK_STATUS_DISCONNECT(sc, SMBDIRECT_SOCKET_RDMA_CONNECT_RUNNING)) ++ break; + sc->status = SMBDIRECT_SOCKET_NEGOTIATE_NEEDED; + wake_up(&sc->status_wait); + break; +-- +2.51.0 + diff --git a/queue-6.18/smb-smbdirect-introduce-smbdirect_check_status_-warn.patch b/queue-6.18/smb-smbdirect-introduce-smbdirect_check_status_-warn.patch new file mode 100644 index 0000000000..de458a2cd4 --- /dev/null +++ b/queue-6.18/smb-smbdirect-introduce-smbdirect_check_status_-warn.patch @@ -0,0 +1,87 @@ +From b0b4426c8e960bf4c9a1ceb844cd7dbfc33854e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 09:55:55 +0100 +Subject: smb: smbdirect: introduce SMBDIRECT_CHECK_STATUS_{WARN,DISCONNECT}() + +From: Stefan Metzmacher + +[ Upstream commit 1adb2dab9727c5beaaf253f67bf4fc2c54ae70e7 ] + +These will be used in various places in order to assert +the current status mostly during the connect and negotiation +phase. It will replace the WARN_ON_ONCE(sc->status != ...) +calls, which are very useless in order to identify the +problem that happened. + +As a start client and server will need to define their own +__SMBDIRECT_SOCKET_DISCONNECT(__sc) macro in order to use +SMBDIRECT_CHECK_STATUS_DISCONNECT(). + +Cc: Steve French +Cc: Tom Talpey +Cc: Long Li +Cc: Namjae Jeon +Cc: Paulo Alcantara +Cc: linux-cifs@vger.kernel.org +Cc: samba-technical@lists.samba.org +Signed-off-by: Stefan Metzmacher +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: 425c32750b48 ("smb: server: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smb_direct_cm_handler()") +Signed-off-by: Sasha Levin +--- + fs/smb/common/smbdirect/smbdirect_socket.h | 38 ++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h +index 611986827a5e2..384b19177e1c3 100644 +--- a/fs/smb/common/smbdirect/smbdirect_socket.h ++++ b/fs/smb/common/smbdirect/smbdirect_socket.h +@@ -394,6 +394,44 @@ static __always_inline void smbdirect_socket_init(struct smbdirect_socket *sc) + init_waitqueue_head(&sc->mr_io.cleanup.wait_queue); + } + ++#define __SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, __error_cmd, __unexpected_cmd) ({ \ ++ bool __failed = false; \ ++ if (unlikely((__sc)->first_error)) { \ ++ __failed = true; \ ++ __error_cmd \ ++ } else if (unlikely((__sc)->status != (__expected_status))) { \ ++ __failed = true; \ ++ __unexpected_cmd \ ++ } \ ++ __failed; \ ++}) ++ ++#define __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, __unexpected_cmd) \ ++ __SMBDIRECT_CHECK_STATUS_FAILED(__sc, __expected_status, \ ++ , \ ++ { \ ++ const struct sockaddr_storage *__src = NULL; \ ++ const struct sockaddr_storage *__dst = NULL; \ ++ if ((__sc)->rdma.cm_id) { \ ++ __src = &(__sc)->rdma.cm_id->route.addr.src_addr; \ ++ __dst = &(__sc)->rdma.cm_id->route.addr.dst_addr; \ ++ } \ ++ WARN_ONCE(1, \ ++ "expected[%s] != %s first_error=%1pe local=%pISpsfc remote=%pISpsfc\n", \ ++ smbdirect_socket_status_string(__expected_status), \ ++ smbdirect_socket_status_string((__sc)->status), \ ++ SMBDIRECT_DEBUG_ERR_PTR((__sc)->first_error), \ ++ __src, __dst); \ ++ __unexpected_cmd \ ++ }) ++ ++#define SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status) \ ++ __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, /* nothing */) ++ ++#define SMBDIRECT_CHECK_STATUS_DISCONNECT(__sc, __expected_status) \ ++ __SMBDIRECT_CHECK_STATUS_WARN(__sc, __expected_status, \ ++ __SMBDIRECT_SOCKET_DISCONNECT(__sc);) ++ + struct smbdirect_send_io { + struct smbdirect_socket *socket; + struct ib_cqe cqe; +-- +2.51.0 + diff --git a/queue-6.18/smb-smbdirect-introduce-smbdirect_debug_err_ptr-help.patch b/queue-6.18/smb-smbdirect-introduce-smbdirect_debug_err_ptr-help.patch new file mode 100644 index 0000000000..b06e6df067 --- /dev/null +++ b/queue-6.18/smb-smbdirect-introduce-smbdirect_debug_err_ptr-help.patch @@ -0,0 +1,61 @@ +From d54c9f016d741ff74fc2a63aee747d71886b8a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 09:55:54 +0100 +Subject: smb: smbdirect: introduce SMBDIRECT_DEBUG_ERR_PTR() helper + +From: Stefan Metzmacher + +[ Upstream commit 1f3fd108c5c5a9885c6c276a2489c49b60a6b90d ] + +This can be used like this: + + int err = somefunc(); + pr_warn("err=%1pe\n", SMBDIRECT_DEBUG_ERR_PTR(err)); + +This will be used in the following fixes in order +to be prepared to identify real world problems +more easily. + +Cc: Steve French +Cc: Tom Talpey +Cc: Long Li +Cc: Namjae Jeon +Cc: Paulo Alcantara +Cc: linux-cifs@vger.kernel.org +Cc: samba-technical@lists.samba.org +Signed-off-by: Stefan Metzmacher +Acked-by: Namjae Jeon +Signed-off-by: Steve French +Stable-dep-of: 425c32750b48 ("smb: server: relax WARN_ON_ONCE(SMBDIRECT_SOCKET_*) checks in recv_done() and smb_direct_cm_handler()") +Signed-off-by: Sasha Levin +--- + fs/smb/common/smbdirect/smbdirect_socket.h | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/fs/smb/common/smbdirect/smbdirect_socket.h b/fs/smb/common/smbdirect/smbdirect_socket.h +index ee5a90d691c89..611986827a5e2 100644 +--- a/fs/smb/common/smbdirect/smbdirect_socket.h ++++ b/fs/smb/common/smbdirect/smbdirect_socket.h +@@ -74,6 +74,19 @@ const char *smbdirect_socket_status_string(enum smbdirect_socket_status status) + return ""; + } + ++/* ++ * This can be used with %1pe to print errors as strings or '0' ++ * And it avoids warnings like: warn: passing zero to 'ERR_PTR' ++ * from smatch -p=kernel --pedantic ++ */ ++static __always_inline ++const void * __must_check SMBDIRECT_DEBUG_ERR_PTR(long error) ++{ ++ if (error == 0) ++ return NULL; ++ return ERR_PTR(error); ++} ++ + enum smbdirect_keepalive_status { + SMBDIRECT_KEEPALIVE_NONE, + SMBDIRECT_KEEPALIVE_PENDING, +-- +2.51.0 + diff --git a/queue-6.18/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch b/queue-6.18/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch new file mode 100644 index 0000000000..50834e5e67 --- /dev/null +++ b/queue-6.18/soc-qcom-gsbi-fix-double-disable-caused-by-devm.patch @@ -0,0 +1,60 @@ +From 12fe6551ecf78cd6ccaee6bed16d28106bb03394 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 00:02:15 +0800 +Subject: soc: qcom: gsbi: fix double disable caused by devm + +From: Haotian Zhang + +[ Upstream commit 2286e18e3937c69cc103308a8c1d4898d8a7b04f ] + +In the commit referenced by the Fixes tag, devm_clk_get_enabled() was +introduced to replace devm_clk_get() and clk_prepare_enable(). While +the clk_disable_unprepare() call in the error path was correctly +removed, the one in the remove function was overlooked, leading to a +double disable issue. + +Remove the redundant clk_disable_unprepare() call from gsbi_remove() +to fix this issue. Since all resources are now managed by devres +and will be automatically released, the remove function serves no purpose +and can be deleted entirely. + +Fixes: 489d7a8cc286 ("soc: qcom: use devm_clk_get_enabled() in gsbi_probe()") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/stable/20251020160215.523-1-vulab%40iscas.ac.cn +Link: https://lore.kernel.org/r/20251020160215.523-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/qcom_gsbi.c | 8 -------- + 1 file changed, 8 deletions(-) + +diff --git a/drivers/soc/qcom/qcom_gsbi.c b/drivers/soc/qcom/qcom_gsbi.c +index 8f1158e0c6313..a25d1de592f06 100644 +--- a/drivers/soc/qcom/qcom_gsbi.c ++++ b/drivers/soc/qcom/qcom_gsbi.c +@@ -212,13 +212,6 @@ static int gsbi_probe(struct platform_device *pdev) + return of_platform_populate(node, NULL, NULL, &pdev->dev); + } + +-static void gsbi_remove(struct platform_device *pdev) +-{ +- struct gsbi_info *gsbi = platform_get_drvdata(pdev); +- +- clk_disable_unprepare(gsbi->hclk); +-} +- + static const struct of_device_id gsbi_dt_match[] = { + { .compatible = "qcom,gsbi-v1.0.0", }, + { }, +@@ -232,7 +225,6 @@ static struct platform_driver gsbi_driver = { + .of_match_table = gsbi_dt_match, + }, + .probe = gsbi_probe, +- .remove = gsbi_remove, + }; + + module_platform_driver(gsbi_driver); +-- +2.51.0 + diff --git a/queue-6.18/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.18/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..1fbab1d823 --- /dev/null +++ b/queue-6.18/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,51 @@ +From 508cee8e6ffa54233ccf3e0206cc7657cd7118e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:27:33 +0800 +Subject: soc: qcom: smem: fix hwspinlock resource leak in probe error paths + +From: Haotian Zhang + +[ Upstream commit dc5db35073a19f6d3c30bea367b551c1a784ef8f ] + +The hwspinlock acquired via hwspin_lock_request_specific() is not +released on several error paths. This results in resource leakage +when probe fails. + +Switch to devm_hwspin_lock_request_specific() to automatically +handle cleanup on probe failure. Remove the manual hwspin_lock_free() +in qcom_smem_remove() as devm handles it automatically. + +Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/smem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index c4c45f15dca4f..f1d1b5aa5e4db 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1190,7 +1190,7 @@ static int qcom_smem_probe(struct platform_device *pdev) + return dev_err_probe(&pdev->dev, hwlock_id, + "failed to retrieve hwlock\n"); + +- smem->hwlock = hwspin_lock_request_specific(hwlock_id); ++ smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); + if (!smem->hwlock) + return -ENXIO; + +@@ -1243,7 +1243,6 @@ static void qcom_smem_remove(struct platform_device *pdev) + { + platform_device_unregister(__smem->socinfo); + +- hwspin_lock_free(__smem->hwlock); + __smem = NULL; + } + +-- +2.51.0 + diff --git a/queue-6.18/soc-renesas-r9a09g056-sys-populate-max_register.patch b/queue-6.18/soc-renesas-r9a09g056-sys-populate-max_register.patch new file mode 100644 index 0000000000..dd97167adf --- /dev/null +++ b/queue-6.18/soc-renesas-r9a09g056-sys-populate-max_register.patch @@ -0,0 +1,34 @@ +From 21103a4ae2a7d98c39cd03ae402e06439442982e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 09:05:25 +0200 +Subject: soc: renesas: r9a09g056-sys: Populate max_register + +From: Claudiu Beznea + +[ Upstream commit 4ff787433ba6d564b00334b4bfd6350f5b6f4bb3 ] + +Populate max_register to avoid external aborts. + +Fixes: 2da2740fb9c8 ("soc: renesas: rz-sysc: Add syscon/regmap support") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251105070526.264445-2-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/soc/renesas/r9a09g056-sys.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/soc/renesas/r9a09g056-sys.c b/drivers/soc/renesas/r9a09g056-sys.c +index 3ad1422eba36e..16b4e433c3373 100644 +--- a/drivers/soc/renesas/r9a09g056-sys.c ++++ b/drivers/soc/renesas/r9a09g056-sys.c +@@ -72,4 +72,5 @@ static const struct rz_sysc_soc_id_init_data rzv2n_sys_soc_id_init_data __initco + + const struct rz_sysc_init_data rzv2n_sys_init_data = { + .soc_id_init_data = &rzv2n_sys_soc_id_init_data, ++ .max_register = 0x170c, + }; +-- +2.51.0 + diff --git a/queue-6.18/soc-renesas-rz-sysc-populate-readable_reg-writeable_.patch b/queue-6.18/soc-renesas-rz-sysc-populate-readable_reg-writeable_.patch new file mode 100644 index 0000000000..f559fcb19b --- /dev/null +++ b/queue-6.18/soc-renesas-rz-sysc-populate-readable_reg-writeable_.patch @@ -0,0 +1,464 @@ +From a5f3475022918518605d6923668abde5c47f8d33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 09:05:26 +0200 +Subject: soc: renesas: rz-sysc: Populate readable_reg/writeable_reg in regmap + config + +From: Claudiu Beznea + +[ Upstream commit c432180a7d95081353a96fd6d5bd75b0fc8a27c3 ] + +Not all system controller registers are accessible from Linux. Accessing +such registers generates synchronous external abort. Populate the +readable_reg and writeable_reg members of the regmap config to inform the +regmap core which registers can be accessed. The list will need to be +updated whenever new system controller functionality is exported through +regmap. + +Fixes: 2da2740fb9c8 ("soc: renesas: rz-sysc: Add syscon/regmap support") +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251105070526.264445-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/soc/renesas/r9a08g045-sysc.c | 69 ++++++++++++++++++ + drivers/soc/renesas/r9a09g047-sys.c | 79 +++++++++++++++++++++ + drivers/soc/renesas/r9a09g056-sys.c | 68 ++++++++++++++++++ + drivers/soc/renesas/r9a09g057-sys.c | 101 +++++++++++++++++++++++++++ + drivers/soc/renesas/rz-sysc.c | 2 + + drivers/soc/renesas/rz-sysc.h | 4 ++ + 6 files changed, 323 insertions(+) + +diff --git a/drivers/soc/renesas/r9a08g045-sysc.c b/drivers/soc/renesas/r9a08g045-sysc.c +index 0504d4e687616..03d653d5cde55 100644 +--- a/drivers/soc/renesas/r9a08g045-sysc.c ++++ b/drivers/soc/renesas/r9a08g045-sysc.c +@@ -6,10 +6,29 @@ + */ + + #include ++#include + #include + + #include "rz-sysc.h" + ++#define SYS_XSPI_MAP_STAADD_CS0 0x348 ++#define SYS_XSPI_MAP_ENDADD_CS0 0x34c ++#define SYS_XSPI_MAP_STAADD_CS1 0x350 ++#define SYS_XSPI_MAP_ENDADD_CS1 0x354 ++#define SYS_GETH0_CFG 0x380 ++#define SYS_GETH1_CFG 0x390 ++#define SYS_PCIE_CFG 0x3a0 ++#define SYS_PCIE_MON 0x3a4 ++#define SYS_PCIE_ERR_MON 0x3ac ++#define SYS_PCIE_PHY 0x3b4 ++#define SYS_I2C0_CFG 0x400 ++#define SYS_I2C1_CFG 0x410 ++#define SYS_I2C2_CFG 0x420 ++#define SYS_I2C3_CFG 0x430 ++#define SYS_I3C_CFG 0x440 ++#define SYS_USB_PWRRDY 0xd70 ++#define SYS_PCIE_RST_RSM_B 0xd74 ++ + static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initconst = { + .family = "RZ/G3S", + .id = 0x85e0447, +@@ -18,7 +37,57 @@ static const struct rz_sysc_soc_id_init_data rzg3s_sysc_soc_id_init_data __initc + .specific_id_mask = GENMASK(27, 0), + }; + ++static bool rzg3s_regmap_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_XSPI_MAP_STAADD_CS0: ++ case SYS_XSPI_MAP_ENDADD_CS0: ++ case SYS_XSPI_MAP_STAADD_CS1: ++ case SYS_XSPI_MAP_ENDADD_CS1: ++ case SYS_GETH0_CFG: ++ case SYS_GETH1_CFG: ++ case SYS_PCIE_CFG: ++ case SYS_PCIE_MON: ++ case SYS_PCIE_ERR_MON: ++ case SYS_PCIE_PHY: ++ case SYS_I2C0_CFG: ++ case SYS_I2C1_CFG: ++ case SYS_I2C2_CFG: ++ case SYS_I2C3_CFG: ++ case SYS_I3C_CFG: ++ case SYS_USB_PWRRDY: ++ case SYS_PCIE_RST_RSM_B: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool rzg3s_regmap_writeable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_XSPI_MAP_STAADD_CS0: ++ case SYS_XSPI_MAP_ENDADD_CS0: ++ case SYS_XSPI_MAP_STAADD_CS1: ++ case SYS_XSPI_MAP_ENDADD_CS1: ++ case SYS_PCIE_CFG: ++ case SYS_PCIE_PHY: ++ case SYS_I2C0_CFG: ++ case SYS_I2C1_CFG: ++ case SYS_I2C2_CFG: ++ case SYS_I2C3_CFG: ++ case SYS_I3C_CFG: ++ case SYS_USB_PWRRDY: ++ case SYS_PCIE_RST_RSM_B: ++ return true; ++ default: ++ return false; ++ } ++} ++ + const struct rz_sysc_init_data rzg3s_sysc_init_data __initconst = { + .soc_id_init_data = &rzg3s_sysc_soc_id_init_data, ++ .readable_reg = rzg3s_regmap_readable_reg, ++ .writeable_reg = rzg3s_regmap_writeable_reg, + .max_register = 0xe20, + }; +diff --git a/drivers/soc/renesas/r9a09g047-sys.c b/drivers/soc/renesas/r9a09g047-sys.c +index 2e8426c030504..e413b0eff9bfd 100644 +--- a/drivers/soc/renesas/r9a09g047-sys.c ++++ b/drivers/soc/renesas/r9a09g047-sys.c +@@ -29,6 +29,27 @@ + #define SYS_LSI_PRR_CA55_DIS BIT(8) + #define SYS_LSI_PRR_NPU_DIS BIT(1) + ++#define SYS_LSI_OTPTSU1TRMVAL0 0x330 ++#define SYS_LSI_OTPTSU1TRMVAL1 0x334 ++#define SYS_SPI_STAADDCS0 0x900 ++#define SYS_SPI_ENDADDCS0 0x904 ++#define SYS_SPI_STAADDCS1 0x908 ++#define SYS_SPI_ENDADDCS1 0x90c ++#define SYS_VSP_CLK 0xe00 ++#define SYS_GBETH0_CFG 0xf00 ++#define SYS_GBETH1_CFG 0xf04 ++#define SYS_PCIE_INTX_CH0 0x1000 ++#define SYS_PCIE_MSI1_CH0 0x1004 ++#define SYS_PCIE_MSI2_CH0 0x1008 ++#define SYS_PCIE_MSI3_CH0 0x100c ++#define SYS_PCIE_MSI4_CH0 0x1010 ++#define SYS_PCIE_MSI5_CH0 0x1014 ++#define SYS_PCIE_PME_CH0 0x1018 ++#define SYS_PCIE_ACK_CH0 0x101c ++#define SYS_PCIE_MISC_CH0 0x1020 ++#define SYS_PCIE_MODE_CH0 0x1024 ++#define SYS_ADC_CFG 0x1600 ++ + static void rzg3e_sys_print_id(struct device *dev, + void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr) +@@ -62,7 +83,65 @@ static const struct rz_sysc_soc_id_init_data rzg3e_sys_soc_id_init_data __initco + .print_id = rzg3e_sys_print_id, + }; + ++static bool rzg3e_regmap_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_LSI_OTPTSU1TRMVAL0: ++ case SYS_LSI_OTPTSU1TRMVAL1: ++ case SYS_SPI_STAADDCS0: ++ case SYS_SPI_ENDADDCS0: ++ case SYS_SPI_STAADDCS1: ++ case SYS_SPI_ENDADDCS1: ++ case SYS_VSP_CLK: ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool rzg3e_regmap_writeable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_SPI_STAADDCS0: ++ case SYS_SPI_ENDADDCS0: ++ case SYS_SPI_STAADDCS1: ++ case SYS_SPI_ENDADDCS1: ++ case SYS_VSP_CLK: ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ + const struct rz_sysc_init_data rzg3e_sys_init_data = { + .soc_id_init_data = &rzg3e_sys_soc_id_init_data, ++ .readable_reg = rzg3e_regmap_readable_reg, ++ .writeable_reg = rzg3e_regmap_writeable_reg, + .max_register = 0x170c, + }; +diff --git a/drivers/soc/renesas/r9a09g056-sys.c b/drivers/soc/renesas/r9a09g056-sys.c +index 16b4e433c3373..42f5eff291fd1 100644 +--- a/drivers/soc/renesas/r9a09g056-sys.c ++++ b/drivers/soc/renesas/r9a09g056-sys.c +@@ -34,6 +34,24 @@ + #define SYS_RZV2N_FEATURE_C55 BIT(1) + #define SYS_RZV2N_FEATURE_SEC BIT(2) + ++#define SYS_LSI_OTPTSU0TRMVAL0 0x320 ++#define SYS_LSI_OTPTSU0TRMVAL1 0x324 ++#define SYS_LSI_OTPTSU1TRMVAL0 0x330 ++#define SYS_LSI_OTPTSU1TRMVAL1 0x334 ++#define SYS_GBETH0_CFG 0xf00 ++#define SYS_GBETH1_CFG 0xf04 ++#define SYS_PCIE_INTX_CH0 0x1000 ++#define SYS_PCIE_MSI1_CH0 0x1004 ++#define SYS_PCIE_MSI2_CH0 0x1008 ++#define SYS_PCIE_MSI3_CH0 0x100c ++#define SYS_PCIE_MSI4_CH0 0x1010 ++#define SYS_PCIE_MSI5_CH0 0x1014 ++#define SYS_PCIE_PME_CH0 0x1018 ++#define SYS_PCIE_ACK_CH0 0x101c ++#define SYS_PCIE_MISC_CH0 0x1020 ++#define SYS_PCIE_MODE_CH0 0x1024 ++#define SYS_ADC_CFG 0x1600 ++ + static void rzv2n_sys_print_id(struct device *dev, + void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr) +@@ -70,7 +88,57 @@ static const struct rz_sysc_soc_id_init_data rzv2n_sys_soc_id_init_data __initco + .print_id = rzv2n_sys_print_id, + }; + ++static bool rzv2n_regmap_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_LSI_OTPTSU0TRMVAL0: ++ case SYS_LSI_OTPTSU0TRMVAL1: ++ case SYS_LSI_OTPTSU1TRMVAL0: ++ case SYS_LSI_OTPTSU1TRMVAL1: ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool rzv2n_regmap_writeable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ + const struct rz_sysc_init_data rzv2n_sys_init_data = { + .soc_id_init_data = &rzv2n_sys_soc_id_init_data, ++ .readable_reg = rzv2n_regmap_readable_reg, ++ .writeable_reg = rzv2n_regmap_writeable_reg, + .max_register = 0x170c, + }; +diff --git a/drivers/soc/renesas/r9a09g057-sys.c b/drivers/soc/renesas/r9a09g057-sys.c +index e3390e7c7fe51..827c718ac7c54 100644 +--- a/drivers/soc/renesas/r9a09g057-sys.c ++++ b/drivers/soc/renesas/r9a09g057-sys.c +@@ -29,6 +29,35 @@ + #define SYS_LSI_PRR_GPU_DIS BIT(0) + #define SYS_LSI_PRR_ISP_DIS BIT(4) + ++#define SYS_LSI_OTPTSU0TRMVAL0 0x320 ++#define SYS_LSI_OTPTSU0TRMVAL1 0x324 ++#define SYS_LSI_OTPTSU1TRMVAL0 0x330 ++#define SYS_LSI_OTPTSU1TRMVAL1 0x334 ++#define SYS_GBETH0_CFG 0xf00 ++#define SYS_GBETH1_CFG 0xf04 ++#define SYS_PCIE_INTX_CH0 0x1000 ++#define SYS_PCIE_MSI1_CH0 0x1004 ++#define SYS_PCIE_MSI2_CH0 0x1008 ++#define SYS_PCIE_MSI3_CH0 0x100c ++#define SYS_PCIE_MSI4_CH0 0x1010 ++#define SYS_PCIE_MSI5_CH0 0x1014 ++#define SYS_PCIE_PME_CH0 0x1018 ++#define SYS_PCIE_ACK_CH0 0x101c ++#define SYS_PCIE_MISC_CH0 0x1020 ++#define SYS_PCIE_MODE_CH0 0x1024 ++#define SYS_PCIE_INTX_CH1 0x1030 ++#define SYS_PCIE_MSI1_CH1 0x1034 ++#define SYS_PCIE_MSI2_CH1 0x1038 ++#define SYS_PCIE_MSI3_CH1 0x103c ++#define SYS_PCIE_MSI4_CH1 0x1040 ++#define SYS_PCIE_MSI5_CH1 0x1044 ++#define SYS_PCIE_PME_CH1 0x1048 ++#define SYS_PCIE_ACK_CH1 0x104c ++#define SYS_PCIE_MISC_CH1 0x1050 ++#define SYS_PCIE_MODE_CH1 0x1054 ++#define SYS_PCIE_MODE 0x1060 ++#define SYS_ADC_CFG 0x1600 ++ + static void rzv2h_sys_print_id(struct device *dev, + void __iomem *sysc_base, + struct soc_device_attribute *soc_dev_attr) +@@ -62,7 +91,79 @@ static const struct rz_sysc_soc_id_init_data rzv2h_sys_soc_id_init_data __initco + .print_id = rzv2h_sys_print_id, + }; + ++static bool rzv2h_regmap_readable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_LSI_OTPTSU0TRMVAL0: ++ case SYS_LSI_OTPTSU0TRMVAL1: ++ case SYS_LSI_OTPTSU1TRMVAL0: ++ case SYS_LSI_OTPTSU1TRMVAL1: ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_PCIE_INTX_CH1: ++ case SYS_PCIE_MSI1_CH1: ++ case SYS_PCIE_MSI2_CH1: ++ case SYS_PCIE_MSI3_CH1: ++ case SYS_PCIE_MSI4_CH1: ++ case SYS_PCIE_MSI5_CH1: ++ case SYS_PCIE_PME_CH1: ++ case SYS_PCIE_ACK_CH1: ++ case SYS_PCIE_MISC_CH1: ++ case SYS_PCIE_MODE_CH1: ++ case SYS_PCIE_MODE: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++static bool rzv2h_regmap_writeable_reg(struct device *dev, unsigned int reg) ++{ ++ switch (reg) { ++ case SYS_GBETH0_CFG: ++ case SYS_GBETH1_CFG: ++ case SYS_PCIE_INTX_CH0: ++ case SYS_PCIE_MSI1_CH0: ++ case SYS_PCIE_MSI2_CH0: ++ case SYS_PCIE_MSI3_CH0: ++ case SYS_PCIE_MSI4_CH0: ++ case SYS_PCIE_MSI5_CH0: ++ case SYS_PCIE_PME_CH0: ++ case SYS_PCIE_ACK_CH0: ++ case SYS_PCIE_MISC_CH0: ++ case SYS_PCIE_MODE_CH0: ++ case SYS_PCIE_INTX_CH1: ++ case SYS_PCIE_MSI1_CH1: ++ case SYS_PCIE_MSI2_CH1: ++ case SYS_PCIE_MSI3_CH1: ++ case SYS_PCIE_MSI4_CH1: ++ case SYS_PCIE_MSI5_CH1: ++ case SYS_PCIE_PME_CH1: ++ case SYS_PCIE_ACK_CH1: ++ case SYS_PCIE_MISC_CH1: ++ case SYS_PCIE_MODE_CH1: ++ case SYS_PCIE_MODE: ++ case SYS_ADC_CFG: ++ return true; ++ default: ++ return false; ++ } ++} ++ + const struct rz_sysc_init_data rzv2h_sys_init_data = { + .soc_id_init_data = &rzv2h_sys_soc_id_init_data, ++ .readable_reg = rzv2h_regmap_readable_reg, ++ .writeable_reg = rzv2h_regmap_writeable_reg, + .max_register = 0x170c, + }; +diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c +index 9f79e299e6f41..19c1e666279b7 100644 +--- a/drivers/soc/renesas/rz-sysc.c ++++ b/drivers/soc/renesas/rz-sysc.c +@@ -140,6 +140,8 @@ static int rz_sysc_probe(struct platform_device *pdev) + regmap_cfg->val_bits = 32; + regmap_cfg->fast_io = true; + regmap_cfg->max_register = data->max_register; ++ regmap_cfg->readable_reg = data->readable_reg; ++ regmap_cfg->writeable_reg = data->writeable_reg; + + regmap = devm_regmap_init_mmio(dev, sysc->base, regmap_cfg); + if (IS_ERR(regmap)) +diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h +index 8eec355d5d562..88929bf21cb11 100644 +--- a/drivers/soc/renesas/rz-sysc.h ++++ b/drivers/soc/renesas/rz-sysc.h +@@ -34,10 +34,14 @@ struct rz_sysc_soc_id_init_data { + /** + * struct rz_sysc_init_data - RZ SYSC initialization data + * @soc_id_init_data: RZ SYSC SoC ID initialization data ++ * @writeable_reg: Regmap writeable register check function ++ * @readable_reg: Regmap readable register check function + * @max_register: Maximum SYSC register offset to be used by the regmap config + */ + struct rz_sysc_init_data { + const struct rz_sysc_soc_id_init_data *soc_id_init_data; ++ bool (*writeable_reg)(struct device *dev, unsigned int reg); ++ bool (*readable_reg)(struct device *dev, unsigned int reg); + u32 max_register; + }; + +-- +2.51.0 + diff --git a/queue-6.18/soc-samsung-exynos-pmu-fix-structure-initialization.patch b/queue-6.18/soc-samsung-exynos-pmu-fix-structure-initialization.patch new file mode 100644 index 0000000000..1463d0d052 --- /dev/null +++ b/queue-6.18/soc-samsung-exynos-pmu-fix-structure-initialization.patch @@ -0,0 +1,71 @@ +From 92b39a203c2bed2a6785f6ff7e2541e8254b5ca7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 12:00:38 +0100 +Subject: soc: samsung: exynos-pmu: Fix structure initialization + +From: Marek Szyprowski + +[ Upstream commit 2224ea67c75d0a0b9eaf803d0dfdab8d0c601c35 ] + +Commit 78b72897a5c8 ("soc: samsung: exynos-pmu: Enable CPU Idle for +gs101") added system wide suspend/resume callbacks to Exynos PMU driver, +but some items used by these callbacks are initialized only on +GS101-compatible boards. Move that initialization to exynos_pmu_probe() +to avoid potential lockdep warnings like below observed during system +suspend/resume cycle: + +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: 0 UID: 0 PID: 2134 Comm: rtcwake Not tainted 6.18.0-rc7-next-20251126-00039-g1d656a1af243 #11794 PREEMPT +Hardware name: Samsung Exynos (Flattened Device Tree) +Call trace: + unwind_backtrace from show_stack+0x10/0x14 + show_stack from dump_stack_lvl+0x68/0x88 + dump_stack_lvl from register_lock_class+0x970/0x988 + register_lock_class from __lock_acquire+0xc8/0x29ec + __lock_acquire from lock_acquire+0x134/0x39c + lock_acquire from _raw_spin_lock+0x38/0x48 + _raw_spin_lock from exynos_cpupm_suspend_noirq+0x18/0x34 + exynos_cpupm_suspend_noirq from dpm_run_callback+0x98/0x2b8 + dpm_run_callback from device_suspend_noirq+0x8c/0x310 + +Fixes: 78b72897a5c8 ("soc: samsung: exynos-pmu: Enable CPU Idle for gs101") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126110038.3326768-1-m.szyprowski@samsung.com +[krzk: include calltrace into commit msg] +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + drivers/soc/samsung/exynos-pmu.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c +index 22c50ca2aa79b..df5b1f299a260 100644 +--- a/drivers/soc/samsung/exynos-pmu.c ++++ b/drivers/soc/samsung/exynos-pmu.c +@@ -585,10 +585,6 @@ static int setup_cpuhp_and_cpuidle(struct device *dev) + if (!pmu_context->in_cpuhp) + return -ENOMEM; + +- raw_spin_lock_init(&pmu_context->cpupm_lock); +- pmu_context->sys_inreboot = false; +- pmu_context->sys_insuspend = false; +- + /* set PMU to power on */ + for_each_online_cpu(cpu) + gs101_cpuhp_pmu_online(cpu); +@@ -657,6 +653,9 @@ static int exynos_pmu_probe(struct platform_device *pdev) + + pmu_context->pmureg = regmap; + pmu_context->dev = dev; ++ raw_spin_lock_init(&pmu_context->cpupm_lock); ++ pmu_context->sys_inreboot = false; ++ pmu_context->sys_insuspend = false; + + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) { + ret = setup_cpuhp_and_cpuidle(dev); +-- +2.51.0 + diff --git a/queue-6.18/soc-tegra-fuse-speedo-tegra210-update-speedo-ids.patch b/queue-6.18/soc-tegra-fuse-speedo-tegra210-update-speedo-ids.patch new file mode 100644 index 0000000000..3c59901fa2 --- /dev/null +++ b/queue-6.18/soc-tegra-fuse-speedo-tegra210-update-speedo-ids.patch @@ -0,0 +1,105 @@ +From cc93364f1c2e436789a3fd6bf937bc39c77b76a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 11:58:05 -0500 +Subject: soc/tegra: fuse: speedo-tegra210: Update speedo IDs + +From: Aaron Kling + +[ Upstream commit ce27c9c2129679551c4e5fe71c1c5d42fff399c2 ] + +Existing code only sets CPU and GPU speedo IDs 0 and 1. The CPU DVFS +code supports 11 IDs and nouveau supports 5. This aligns with what the +downstream vendor kernel supports. Align SKUs with the downstream list. + +The Tegra210 CVB tables were added in the first referenced fixes commit. +Since then, all Tegra210 SoCs have tried to scale to 1.9 GHz, when the +supported devkits are only supposed to scale to 1.5 or 1.7 GHZ. +Overclocking should not be the default state. + +Fixes: 2b2dbc2f94e5 ("clk: tegra: dfll: add CVB tables for Tegra210") +Fixes: 579db6e5d9b8 ("arm64: tegra: Enable DFLL support on Jetson Nano") +Signed-off-by: Aaron Kling +Signed-off-by: Thierry Reding +Signed-off-by: Sasha Levin +--- + drivers/soc/tegra/fuse/speedo-tegra210.c | 62 ++++++++++++++++-------- + 1 file changed, 43 insertions(+), 19 deletions(-) + +diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c +index 695d0b7f9a8ab..a8cc363297723 100644 +--- a/drivers/soc/tegra/fuse/speedo-tegra210.c ++++ b/drivers/soc/tegra/fuse/speedo-tegra210.c +@@ -65,27 +65,51 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, + sku_info->gpu_speedo_id = 0; + *threshold = THRESHOLD_INDEX_0; + +- switch (sku) { +- case 0x00: /* Engineering SKU */ +- case 0x01: /* Engineering SKU */ +- case 0x07: +- case 0x17: +- case 0x27: +- if (speedo_rev >= 2) ++ if (sku_info->revision >= TEGRA_REVISION_A02) { ++ switch (sku) { ++ case 0x00: /* Engineering SKU */ ++ case 0x01: /* Engineering SKU */ ++ case 0x13: ++ sku_info->cpu_speedo_id = 5; ++ sku_info->gpu_speedo_id = 2; ++ break; ++ ++ case 0x07: ++ case 0x17: ++ case 0x1F: ++ sku_info->cpu_speedo_id = 7; ++ sku_info->gpu_speedo_id = 2; ++ break; ++ ++ case 0x27: ++ sku_info->cpu_speedo_id = 1; ++ sku_info->gpu_speedo_id = 2; ++ break; ++ ++ case 0x83: ++ sku_info->cpu_speedo_id = 3; ++ sku_info->gpu_speedo_id = 3; ++ break; ++ ++ case 0x87: ++ sku_info->cpu_speedo_id = 2; + sku_info->gpu_speedo_id = 1; +- break; +- +- case 0x13: +- if (speedo_rev >= 2) +- sku_info->gpu_speedo_id = 1; +- +- sku_info->cpu_speedo_id = 1; +- break; +- +- default: ++ break; ++ ++ case 0x8F: ++ sku_info->cpu_speedo_id = 9; ++ sku_info->gpu_speedo_id = 2; ++ break; ++ ++ default: ++ pr_err("Tegra210: unknown revision 2 or newer SKU %#04x\n", sku); ++ /* Using the default for the error case */ ++ break; ++ } ++ } else if (sku == 0x00 || sku == 0x01 || sku == 0x07 || sku == 0x13 || sku == 0x17) { ++ sku_info->gpu_speedo_id = 1; ++ } else { + pr_err("Tegra210: unknown SKU %#04x\n", sku); +- /* Using the default for the error case */ +- break; + } + } + +-- +2.51.0 + diff --git a/queue-6.18/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch b/queue-6.18/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch new file mode 100644 index 0000000000..3fdf1394f5 --- /dev/null +++ b/queue-6.18/spi-airoha-snfi-en7523-workaround-flash-damaging-if-.patch @@ -0,0 +1,112 @@ +From c12800138c5ccda405f7874c82759ec6e334dc19 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 02:40:45 +0300 +Subject: spi: airoha-snfi: en7523: workaround flash damaging if UART_TXD was + short to GND + +From: Mikhail Kshevetskiy + +[ Upstream commit 061795b345aff371df8f71d54ae7c7dc8ae630d0 ] + +Airoha EN7523 specific bug +-------------------------- +We found that some serial console may pull TX line to GROUND during board +boot time. Airoha uses TX line as one of its bootstrap pins. On the EN7523 +SoC this may lead to booting in RESERVED boot mode. + +It was found that some flashes operates incorrectly in RESERVED mode. +Micron and Skyhigh flashes are definitely affected by the issue, +Winbond flashes are not affected. + +Details: +-------- +DMA reading of odd pages on affected flashes operates incorrectly. Page +reading offset (start of the page) on hardware level is replaced by 0x10. +Thus results in incorrect data reading. As result OS loading becomes +impossible. + +Usage of UBI make things even worse. On attaching, UBI will detects +corruptions (because of wrong reading of odd pages) and will try to +recover. For recovering UBI will erase and write 'damaged' blocks with +a valid information. This will destroy all UBI data. + +Non-DMA reading is OK. + +This patch detects booting in reserved mode, turn off DMA and print big +fat warning. + +It's worth noting that the boot configuration is preserved across reboots. +Therefore, to boot normally, you should do the following: +- disconnect the serial console from the board, +- power cycle the board. + +Fixes: a403997c12019 ("spi: airoha: add SPI-NAND Flash controller driver") +Signed-off-by: Mikhail Kshevetskiy +Reviewed-by: AngeloGioacchino Del Regno +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251125234047.1101985-2-mikhail.kshevetskiy@iopsys.eu +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-airoha-snfi.c | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-airoha-snfi.c b/drivers/spi/spi-airoha-snfi.c +index b78163eaed61d..20b5d469d519a 100644 +--- a/drivers/spi/spi-airoha-snfi.c ++++ b/drivers/spi/spi-airoha-snfi.c +@@ -1030,6 +1030,11 @@ static const struct spi_controller_mem_ops airoha_snand_mem_ops = { + .dirmap_write = airoha_snand_dirmap_write, + }; + ++static const struct spi_controller_mem_ops airoha_snand_nodma_mem_ops = { ++ .supports_op = airoha_snand_supports_op, ++ .exec_op = airoha_snand_exec_op, ++}; ++ + static int airoha_snand_setup(struct spi_device *spi) + { + struct airoha_snand_ctrl *as_ctrl; +@@ -1104,7 +1109,9 @@ static int airoha_snand_probe(struct platform_device *pdev) + struct airoha_snand_ctrl *as_ctrl; + struct device *dev = &pdev->dev; + struct spi_controller *ctrl; ++ bool dma_enable = true; + void __iomem *base; ++ u32 sfc_strap; + int err; + + ctrl = devm_spi_alloc_host(dev, sizeof(*as_ctrl)); +@@ -1139,12 +1146,28 @@ static int airoha_snand_probe(struct platform_device *pdev) + return dev_err_probe(dev, PTR_ERR(as_ctrl->spi_clk), + "unable to get spi clk\n"); + ++ if (device_is_compatible(dev, "airoha,en7523-snand")) { ++ err = regmap_read(as_ctrl->regmap_ctrl, ++ REG_SPI_CTRL_SFC_STRAP, &sfc_strap); ++ if (err) ++ return err; ++ ++ if (!(sfc_strap & 0x04)) { ++ dma_enable = false; ++ dev_warn(dev, "Detected booting in RESERVED mode (UART_TXD was short to GND).\n"); ++ dev_warn(dev, "This mode is known for incorrect DMA reading of some flashes.\n"); ++ dev_warn(dev, "Much slower PIO mode will be used to prevent flash data damage.\n"); ++ dev_warn(dev, "Unplug UART cable and power cycle board to get full performance.\n"); ++ } ++ } ++ + err = dma_set_mask(as_ctrl->dev, DMA_BIT_MASK(32)); + if (err) + return err; + + ctrl->num_chipselect = 2; +- ctrl->mem_ops = &airoha_snand_mem_ops; ++ ctrl->mem_ops = dma_enable ? &airoha_snand_mem_ops ++ : &airoha_snand_nodma_mem_ops; + ctrl->bits_per_word_mask = SPI_BPW_MASK(8); + ctrl->mode_bits = SPI_RX_DUAL; + ctrl->setup = airoha_snand_setup; +-- +2.51.0 + diff --git a/queue-6.18/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch b/queue-6.18/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch new file mode 100644 index 0000000000..6868ab5f89 --- /dev/null +++ b/queue-6.18/spi-ch341-fix-out-of-bounds-memory-access-in-ch341_t.patch @@ -0,0 +1,50 @@ +From 3628e9e77f472136c4e794963989ac72bc554311 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 16:06:30 +0800 +Subject: spi: ch341: fix out-of-bounds memory access in ch341_transfer_one + +From: Tianchu Chen + +[ Upstream commit 545d1287e40a55242f6ab68bcc1ba3b74088b1bc ] + +Discovered by Atuin - Automated Vulnerability Discovery Engine. + +The 'len' variable is calculated as 'min(32, trans->len + 1)', +which includes the 1-byte command header. + +When copying data from 'trans->tx_buf' to 'ch341->tx_buf + 1', using 'len' +as the length is incorrect because: + +1. It causes an out-of-bounds read from 'trans->tx_buf' (which has size + 'trans->len', i.e., 'len - 1' in this context). +2. It can cause an out-of-bounds write to 'ch341->tx_buf' if 'len' is + CH341_PACKET_LENGTH (32). Writing 32 bytes to ch341->tx_buf + 1 + overflows the buffer. + +Fix this by copying 'len - 1' bytes. + +Fixes: 8846739f52af ("spi: add ch341a usb2spi driver") +Signed-off-by: Tianchu Chen +Link: https://patch.msgid.link/20251128160630.0f922c45ec6084a46fb57099@linux.dev +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-ch341.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c +index 46bc208f2d050..79d2f9ab4ef03 100644 +--- a/drivers/spi/spi-ch341.c ++++ b/drivers/spi/spi-ch341.c +@@ -78,7 +78,7 @@ static int ch341_transfer_one(struct spi_controller *host, + + ch341->tx_buf[0] = CH341A_CMD_SPI_STREAM; + +- memcpy(ch341->tx_buf + 1, trans->tx_buf, len); ++ memcpy(ch341->tx_buf + 1, trans->tx_buf, len - 1); + + ret = usb_bulk_msg(ch341->udev, ch341->write_pipe, ch341->tx_buf, len, + NULL, CH341_DEFAULT_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.18/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch b/queue-6.18/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch new file mode 100644 index 0000000000..93a26533ec --- /dev/null +++ b/queue-6.18/spi-sophgo-fix-incorrect-use-of-bus-width-value-macr.patch @@ -0,0 +1,47 @@ +From 1062646bddfcb1c6c929ace09547446e2df6e09c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 17:05:39 +0800 +Subject: spi: sophgo: Fix incorrect use of bus width value macros + +From: Longbin Li + +[ Upstream commit d9813cd23d5a7b254cc1b1c1ea042634d8da62e6 ] + +The previous code initialized the 'reg' value with specific bus-width +values (BUS_WIDTH_2_BIT and BUS_WIDTH_4_BIT), which introduces ambiguity. +Replace them with BUS_WIDTH_MASK to express the intention clearly. + +Fixes: de16c322eefb ("spi: sophgo: add SG2044 SPI NOR controller driver") +Signed-off-by: Longbin Li +Link: https://patch.msgid.link/20251117090559.78288-1-looong.bin@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-sg2044-nor.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-sg2044-nor.c b/drivers/spi/spi-sg2044-nor.c +index af48b1fcda930..37f1cfe10be46 100644 +--- a/drivers/spi/spi-sg2044-nor.c ++++ b/drivers/spi/spi-sg2044-nor.c +@@ -42,6 +42,7 @@ + #define SPIFMC_TRAN_CSR_TRAN_MODE_RX BIT(0) + #define SPIFMC_TRAN_CSR_TRAN_MODE_TX BIT(1) + #define SPIFMC_TRAN_CSR_FAST_MODE BIT(3) ++#define SPIFMC_TRAN_CSR_BUS_WIDTH_MASK GENMASK(5, 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_1_BIT (0x00 << 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT (0x01 << 4) + #define SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT (0x02 << 4) +@@ -122,8 +123,7 @@ static u32 sg2044_spifmc_init_reg(struct sg2044_spifmc *spifmc) + reg = readl(spifmc->io_base + SPIFMC_TRAN_CSR); + reg &= ~(SPIFMC_TRAN_CSR_TRAN_MODE_MASK | + SPIFMC_TRAN_CSR_FAST_MODE | +- SPIFMC_TRAN_CSR_BUS_WIDTH_2_BIT | +- SPIFMC_TRAN_CSR_BUS_WIDTH_4_BIT | ++ SPIFMC_TRAN_CSR_BUS_WIDTH_MASK | + SPIFMC_TRAN_CSR_DMA_EN | + SPIFMC_TRAN_CSR_ADDR_BYTES_MASK | + SPIFMC_TRAN_CSR_WITH_CMD | +-- +2.51.0 + diff --git a/queue-6.18/spi-tegra210-quad-fix-timeout-handling.patch b/queue-6.18/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..6b514e804b --- /dev/null +++ b/queue-6.18/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,117 @@ +From 9f2523cb5664a83cdfd8c6eed60b29661477efd6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index 3be7499db21ec..d9ca3d7b082f2 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -1024,8 +1024,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1176,9 +1178,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1200,11 +1204,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + ret = 0; + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1290,6 +1296,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1395,6 +1403,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1480,6 +1489,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-6.18/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-6.18/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..6430be6f46 --- /dev/null +++ b/queue-6.18/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From 6a687ffa5965c5de1b18f52850982a03b06e35ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index 9e7b84071174c..8a5ccc8ae0a18 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1171,8 +1171,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-6.18/staging-most-remove-broken-i2c-driver.patch b/queue-6.18/staging-most-remove-broken-i2c-driver.patch new file mode 100644 index 0000000000..d9d1c48dfd --- /dev/null +++ b/queue-6.18/staging-most-remove-broken-i2c-driver.patch @@ -0,0 +1,467 @@ +From 7142899fdbf6e75fe647481be3af7bf59a4fa622 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:34:42 +0100 +Subject: staging: most: remove broken i2c driver + +From: Johan Hovold + +[ Upstream commit 495df2da6944477d282d5cc0c13174d06e25b310 ] + +The MOST I2C driver has been completely broken for five years without +anyone noticing so remove the driver from staging. + +Specifically, commit 723de0f9171e ("staging: most: remove device from +interface structure") started requiring drivers to set the interface +device pointer before registration, but the I2C driver was never updated +which results in a NULL pointer dereference if anyone ever tries to +probe it. + +Fixes: 723de0f9171e ("staging: most: remove device from interface structure") +Cc: Christian Gromm +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20251029093442.29256-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/most/Kconfig | 2 - + drivers/staging/most/Makefile | 1 - + drivers/staging/most/i2c/Kconfig | 13 -- + drivers/staging/most/i2c/Makefile | 4 - + drivers/staging/most/i2c/i2c.c | 374 ------------------------------ + 5 files changed, 394 deletions(-) + delete mode 100644 drivers/staging/most/i2c/Kconfig + delete mode 100644 drivers/staging/most/i2c/Makefile + delete mode 100644 drivers/staging/most/i2c/i2c.c + +diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig +index 6f420cbcdcfff..e89658df6f124 100644 +--- a/drivers/staging/most/Kconfig ++++ b/drivers/staging/most/Kconfig +@@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig" + + source "drivers/staging/most/dim2/Kconfig" + +-source "drivers/staging/most/i2c/Kconfig" +- + endif +diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile +index 8b3fc5a7af514..e45084df7803a 100644 +--- a/drivers/staging/most/Makefile ++++ b/drivers/staging/most/Makefile +@@ -3,4 +3,3 @@ + obj-$(CONFIG_MOST_NET) += net/ + obj-$(CONFIG_MOST_VIDEO) += video/ + obj-$(CONFIG_MOST_DIM2) += dim2/ +-obj-$(CONFIG_MOST_I2C) += i2c/ +diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig +deleted file mode 100644 +index ff64283cbad18..0000000000000 +--- a/drivers/staging/most/i2c/Kconfig ++++ /dev/null +@@ -1,13 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-# +-# MOST I2C configuration +-# +- +-config MOST_I2C +- tristate "I2C" +- depends on I2C +- help +- Say Y here if you want to connect via I2C to network transceiver. +- +- To compile this driver as a module, choose M here: the +- module will be called most_i2c. +diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile +deleted file mode 100644 +index 71099dd0f85b9..0000000000000 +--- a/drivers/staging/most/i2c/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_MOST_I2C) += most_i2c.o +- +-most_i2c-objs := i2c.o +diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c +deleted file mode 100644 +index 184b2dd11fc34..0000000000000 +--- a/drivers/staging/most/i2c/i2c.c ++++ /dev/null +@@ -1,374 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * i2c.c - Hardware Dependent Module for I2C Interface +- * +- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-enum { CH_RX, CH_TX, NUM_CHANNELS }; +- +-#define MAX_BUFFERS_CONTROL 32 +-#define MAX_BUF_SIZE_CONTROL 256 +- +-/** +- * list_first_mbo - get the first mbo from a list +- * @ptr: the list head to take the mbo from. +- */ +-#define list_first_mbo(ptr) \ +- list_first_entry(ptr, struct mbo, list) +- +-static unsigned int polling_rate; +-module_param(polling_rate, uint, 0644); +-MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)"); +- +-struct hdm_i2c { +- struct most_interface most_iface; +- struct most_channel_capability capabilities[NUM_CHANNELS]; +- struct i2c_client *client; +- struct rx { +- struct delayed_work dwork; +- struct list_head list; +- bool int_disabled; +- unsigned int delay; +- } rx; +- char name[64]; +-}; +- +-static inline struct hdm_i2c *to_hdm(struct most_interface *iface) +-{ +- return container_of(iface, struct hdm_i2c, most_iface); +-} +- +-static irqreturn_t most_irq_handler(int, void *); +-static void pending_rx_work(struct work_struct *); +- +-/** +- * configure_channel - called from MOST core to configure a channel +- * @most_iface: interface the channel belongs to +- * @ch_idx: channel to be configured +- * @channel_config: structure that holds the configuration information +- * +- * Return 0 on success, negative on failure. +- * +- * Receives configuration information from MOST core and initialize the +- * corresponding channel. +- */ +-static int configure_channel(struct most_interface *most_iface, +- int ch_idx, +- struct most_channel_config *channel_config) +-{ +- int ret; +- struct hdm_i2c *dev = to_hdm(most_iface); +- unsigned int delay, pr; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (channel_config->data_type != MOST_CH_CONTROL) { +- pr_err("bad data type for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction != dev->capabilities[ch_idx].direction) { +- pr_err("bad direction for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction == MOST_CH_RX) { +- if (!polling_rate) { +- if (dev->client->irq <= 0) { +- pr_err("bad irq: %d\n", dev->client->irq); +- return -ENOENT; +- } +- dev->rx.int_disabled = false; +- ret = request_irq(dev->client->irq, most_irq_handler, 0, +- dev->client->name, dev); +- if (ret) { +- pr_err("request_irq(%d) failed: %d\n", +- dev->client->irq, ret); +- return ret; +- } +- } else { +- delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate); +- dev->rx.delay = delay ? delay : 1; +- pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay); +- pr_info("polling rate is %u Hz\n", pr); +- } +- } +- +- return 0; +-} +- +-/** +- * enqueue - called from MOST core to enqueue a buffer for data transfer +- * @most_iface: intended interface +- * @ch_idx: ID of the channel the buffer is intended for +- * @mbo: pointer to the buffer object +- * +- * Return 0 on success, negative on failure. +- * +- * Transmit the data over I2C if it is a "write" request or push the buffer into +- * list if it is an "read" request +- */ +-static int enqueue(struct most_interface *most_iface, +- int ch_idx, struct mbo *mbo) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- int ret; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- /* RX */ +- if (!polling_rate) +- disable_irq(dev->client->irq); +- cancel_delayed_work_sync(&dev->rx.dwork); +- list_add_tail(&mbo->list, &dev->rx.list); +- if (dev->rx.int_disabled || polling_rate) +- pending_rx_work(&dev->rx.dwork.work); +- if (!polling_rate) +- enable_irq(dev->client->irq); +- } else { +- /* TX */ +- ret = i2c_master_send(dev->client, mbo->virt_address, +- mbo->buffer_length); +- if (ret <= 0) { +- mbo->processed_length = 0; +- mbo->status = MBO_E_INVAL; +- } else { +- mbo->processed_length = mbo->buffer_length; +- mbo->status = MBO_SUCCESS; +- } +- mbo->complete(mbo); +- } +- +- return 0; +-} +- +-/** +- * poison_channel - called from MOST core to poison buffers of a channel +- * @most_iface: pointer to the interface the channel to be poisoned belongs to +- * @ch_idx: corresponding channel ID +- * +- * Return 0 on success, negative on failure. +- * +- * If channel direction is RX, complete the buffers in list with +- * status MBO_E_CLOSE +- */ +-static int poison_channel(struct most_interface *most_iface, +- int ch_idx) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- struct mbo *mbo; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- if (!polling_rate) +- free_irq(dev->client->irq, dev); +- cancel_delayed_work_sync(&dev->rx.dwork); +- +- while (!list_empty(&dev->rx.list)) { +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = 0; +- mbo->status = MBO_E_CLOSE; +- mbo->complete(mbo); +- } +- } +- +- return 0; +-} +- +-static void do_rx_work(struct hdm_i2c *dev) +-{ +- struct mbo *mbo; +- unsigned char msg[MAX_BUF_SIZE_CONTROL]; +- int ret; +- u16 pml, data_size; +- +- /* Read PML (2 bytes) */ +- ret = i2c_master_recv(dev->client, msg, 2); +- if (ret <= 0) { +- pr_err("Failed to receive PML\n"); +- return; +- } +- +- pml = (msg[0] << 8) | msg[1]; +- if (!pml) +- return; +- +- data_size = pml + 2; +- +- /* Read the whole message, including PML */ +- ret = i2c_master_recv(dev->client, msg, data_size); +- if (ret <= 0) { +- pr_err("Failed to receive a Port Message\n"); +- return; +- } +- +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = min(data_size, mbo->buffer_length); +- memcpy(mbo->virt_address, msg, mbo->processed_length); +- mbo->status = MBO_SUCCESS; +- mbo->complete(mbo); +-} +- +-/** +- * pending_rx_work - Read pending messages through I2C +- * @work: definition of this work item +- * +- * Invoked by the Interrupt Service Routine, most_irq_handler() +- */ +-static void pending_rx_work(struct work_struct *work) +-{ +- struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work); +- +- if (list_empty(&dev->rx.list)) +- return; +- +- do_rx_work(dev); +- +- if (polling_rate) { +- schedule_delayed_work(&dev->rx.dwork, dev->rx.delay); +- } else { +- dev->rx.int_disabled = false; +- enable_irq(dev->client->irq); +- } +-} +- +-/* +- * most_irq_handler - Interrupt Service Routine +- * @irq: irq number +- * @_dev: private data +- * +- * Schedules a delayed work +- * +- * By default the interrupt line behavior is Active Low. Once an interrupt is +- * generated by the device, until driver clears the interrupt (by reading +- * the PMP message), device keeps the interrupt line in low state. Since i2c +- * read is done in work queue, the interrupt line must be disabled temporarily +- * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue, +- * after reading the message. +- * +- * Note: If we use the interrupt line in Falling edge mode, there is a +- * possibility to miss interrupts when ISR is getting executed. +- * +- */ +-static irqreturn_t most_irq_handler(int irq, void *_dev) +-{ +- struct hdm_i2c *dev = _dev; +- +- disable_irq_nosync(irq); +- dev->rx.int_disabled = true; +- schedule_delayed_work(&dev->rx.dwork, 0); +- +- return IRQ_HANDLED; +-} +- +-/* +- * i2c_probe - i2c probe handler +- * @client: i2c client device structure +- * @id: i2c client device id +- * +- * Return 0 on success, negative on failure. +- * +- * Register the i2c client device as a MOST interface +- */ +-static int i2c_probe(struct i2c_client *client) +-{ +- struct hdm_i2c *dev; +- int ret, i; +- +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); +- if (!dev) +- return -ENOMEM; +- +- /* ID format: i2c--
*/ +- snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x", +- client->adapter->nr, client->addr); +- +- for (i = 0; i < NUM_CHANNELS; i++) { +- dev->capabilities[i].data_type = MOST_CH_CONTROL; +- dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL; +- dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL; +- } +- dev->capabilities[CH_RX].direction = MOST_CH_RX; +- dev->capabilities[CH_RX].name_suffix = "rx"; +- dev->capabilities[CH_TX].direction = MOST_CH_TX; +- dev->capabilities[CH_TX].name_suffix = "tx"; +- +- dev->most_iface.interface = ITYPE_I2C; +- dev->most_iface.description = dev->name; +- dev->most_iface.num_channels = NUM_CHANNELS; +- dev->most_iface.channel_vector = dev->capabilities; +- dev->most_iface.configure = configure_channel; +- dev->most_iface.enqueue = enqueue; +- dev->most_iface.poison_channel = poison_channel; +- +- INIT_LIST_HEAD(&dev->rx.list); +- +- INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work); +- +- dev->client = client; +- i2c_set_clientdata(client, dev); +- +- ret = most_register_interface(&dev->most_iface); +- if (ret) { +- pr_err("Failed to register i2c as a MOST interface\n"); +- kfree(dev); +- return ret; +- } +- +- return 0; +-} +- +-/* +- * i2c_remove - i2c remove handler +- * @client: i2c client device structure +- * +- * Return 0 on success. +- * +- * Unregister the i2c client device as a MOST interface +- */ +-static void i2c_remove(struct i2c_client *client) +-{ +- struct hdm_i2c *dev = i2c_get_clientdata(client); +- +- most_deregister_interface(&dev->most_iface); +- kfree(dev); +-} +- +-static const struct i2c_device_id i2c_id[] = { +- { "most_i2c" }, +- { } /* Terminating entry */ +-}; +- +-MODULE_DEVICE_TABLE(i2c, i2c_id); +- +-static struct i2c_driver i2c_driver = { +- .driver = { +- .name = "hdm_i2c", +- }, +- .probe = i2c_probe, +- .remove = i2c_remove, +- .id_table = i2c_id, +-}; +- +-module_i2c_driver(i2c_driver); +- +-MODULE_AUTHOR("Andrey Shvetsov "); +-MODULE_DESCRIPTION("I2C Hardware Dependent Module"); +-MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.18/task_work-fix-nmi-race-condition.patch b/queue-6.18/task_work-fix-nmi-race-condition.patch new file mode 100644 index 0000000000..d60f5578b3 --- /dev/null +++ b/queue-6.18/task_work-fix-nmi-race-condition.patch @@ -0,0 +1,62 @@ +From 5264923874409368f3db334f2d803f102a14788b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 15:47:00 +0200 +Subject: task_work: Fix NMI race condition + +From: Peter Zijlstra + +[ Upstream commit ef1ea98c8fffe227e5319215d84a53fa2a4bcebc ] + + __schedule() + // disable irqs + + task_work_add(current, work, TWA_NMI_CURRENT); + + // current = next; + // enable irqs + + task_work_set_notify_irq() + test_and_set_tsk_thread_flag(current, + TIF_NOTIFY_RESUME); // wrong task! + + // original task skips task work on its next return to user (or exit!) + +Fixes: 466e4d801cd4 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode.") +Reported-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Steven Rostedt (Google) +Link: https://patch.msgid.link/20250924080118.425949403@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/task_work.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/task_work.c b/kernel/task_work.c +index d1efec571a4a4..0f7519f8e7c93 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -9,7 +9,12 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ + #ifdef CONFIG_IRQ_WORK + static void task_work_set_notify_irq(struct irq_work *entry) + { +- test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); ++ /* ++ * no-op IPI ++ * ++ * TWA_NMI_CURRENT will already have set the TIF flag, all ++ * this interrupt does it tickle the return-to-user path. ++ */ + } + static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = + IRQ_WORK_INIT_HARD(task_work_set_notify_irq); +@@ -86,6 +91,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, + break; + #ifdef CONFIG_IRQ_WORK + case TWA_NMI_CURRENT: ++ set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); + irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); + break; + #endif +-- +2.51.0 + diff --git a/queue-6.18/timers-migration-convert-while-loops-to-use-for.patch b/queue-6.18/timers-migration-convert-while-loops-to-use-for.patch new file mode 100644 index 0000000000..d2e3bd2029 --- /dev/null +++ b/queue-6.18/timers-migration-convert-while-loops-to-use-for.patch @@ -0,0 +1,83 @@ +From 4a567ede72b3647630acb4d1be5259c67e3bb2da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:31 +0200 +Subject: timers/migration: Convert "while" loops to use "for" + +From: Frederic Weisbecker + +[ Upstream commit 6c181b5667eea3e6564d334443536a5974190e15 ] + +Both the "do while" and "while" loops in tmigr_setup_groups() eventually +mimic the behaviour of "for" loops. + +Simplify accordingly. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-2-frederic@kernel.org +Stable-dep-of: 5eb579dfd46b ("timers/migration: Fix imbalanced NUMA trees") +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index c0c54dc5314c3..1e371f1fdc86c 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -1642,22 +1642,23 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + { + struct tmigr_group *group, *child, **stack; +- int top = 0, err = 0, i = 0; ++ int i, top = 0, err = 0; + struct list_head *lvllist; + + stack = kcalloc(tmigr_hierarchy_levels, sizeof(*stack), GFP_KERNEL); + if (!stack) + return -ENOMEM; + +- do { ++ for (i = 0; i < tmigr_hierarchy_levels; i++) { + group = tmigr_get_group(cpu, node, i); + if (IS_ERR(group)) { + err = PTR_ERR(group); ++ i--; + break; + } + + top = i; +- stack[i++] = group; ++ stack[i] = group; + + /* + * When booting only less CPUs of a system than CPUs are +@@ -1667,16 +1668,18 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + * be different from tmigr_hierarchy_levels, contains only a + * single group. + */ +- if (group->parent || list_is_singular(&tmigr_level_list[i - 1])) ++ if (group->parent || list_is_singular(&tmigr_level_list[i])) + break; ++ } + +- } while (i < tmigr_hierarchy_levels); +- +- /* Assert single root */ +- WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top])); ++ /* Assert single root without parent */ ++ if (WARN_ON_ONCE(i >= tmigr_hierarchy_levels)) ++ return -EINVAL; ++ if (WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top]))) ++ return -EINVAL; + +- while (i > 0) { +- group = stack[--i]; ++ for (; i >= 0; i--) { ++ group = stack[i]; + + if (err < 0) { + list_del(&group->list); +-- +2.51.0 + diff --git a/queue-6.18/timers-migration-fix-imbalanced-numa-trees.patch b/queue-6.18/timers-migration-fix-imbalanced-numa-trees.patch new file mode 100644 index 0000000000..5310a0c683 --- /dev/null +++ b/queue-6.18/timers-migration-fix-imbalanced-numa-trees.patch @@ -0,0 +1,441 @@ +From fc0c3f22f6758b789aa56b207e2274293c0fb341 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:33 +0200 +Subject: timers/migration: Fix imbalanced NUMA trees + +From: Frederic Weisbecker + +[ Upstream commit 5eb579dfd46b4949117ecb0f1ba2f12d3dc9a6f2 ] + +When a CPU from a new node boots, the old root may happen to be +connected to the new root even if their node mismatch, as depicted in +the following scenario: + +1) CPU 0 boots and creates the first group for node 0. + + [GRP0:0] + node 0 + | + CPU 0 + +2) CPU 1 from node 1 boots and creates a new top that corresponds to + node 1, but it also connects the old root from node 0 to the new root + from node 1 by mistake. + + [GRP1:0] + node 1 + / \ + / \ + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0 CPU 1 + +3) This eventually leads to an imbalanced tree where some node 0 CPUs + migrate node 1 timers (and vice versa) way before reaching the + crossnode groups, resulting in more frequent remote memory accesses + than expected. + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:1] + node 1 node 0 + / \ | + / \ [...] + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0... CPU 1... + +A balanced tree should only contain groups having children that belong +to the same node: + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:0] + node 0 node 1 + / \ / \ + / \ / \ + [GRP0:0] [...] [...] [GRP0:1] + node 0 node 1 + | | + CPU 0... CPU 1... + +In order to fix this, the hierarchy must be unfolded up to the crossnode +level as soon as a node mismatch is detected. For example the stage 2 +above should lead to this layout: + + [GRP2:0] + NUMA_NO_NODE + / \ + [GRP1:0] [GRP1:1] + node 0 node 1 + / \ + / \ + [GRP0:0] [GRP0:1] + node 0 node 1 + | | + CPU 0 CPU 1 + +This means that not only GRP1:0 must be created but also GRP1:1 and +GRP2:0 in order to prepare a balanced tree for next CPUs to boot. + +Fixes: 7ee988770326 ("timers: Implement the hierarchical pull model") +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-4-frederic@kernel.org +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 231 +++++++++++++++++++--------------- + 1 file changed, 127 insertions(+), 104 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index 5f8aef94ca0f7..49635a2b7ee28 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -420,6 +420,8 @@ static struct list_head *tmigr_level_list __read_mostly; + static unsigned int tmigr_hierarchy_levels __read_mostly; + static unsigned int tmigr_crossnode_level __read_mostly; + ++static struct tmigr_group *tmigr_root; ++ + static DEFINE_PER_CPU(struct tmigr_cpu, tmigr_cpu); + + #define TMIGR_NONE 0xFF +@@ -522,11 +524,9 @@ struct tmigr_walk { + + typedef bool (*up_f)(struct tmigr_group *, struct tmigr_group *, struct tmigr_walk *); + +-static void __walk_groups(up_f up, struct tmigr_walk *data, +- struct tmigr_cpu *tmc) ++static void __walk_groups_from(up_f up, struct tmigr_walk *data, ++ struct tmigr_group *child, struct tmigr_group *group) + { +- struct tmigr_group *child = NULL, *group = tmc->tmgroup; +- + do { + WARN_ON_ONCE(group->level >= tmigr_hierarchy_levels); + +@@ -544,6 +544,12 @@ static void __walk_groups(up_f up, struct tmigr_walk *data, + } while (group); + } + ++static void __walk_groups(up_f up, struct tmigr_walk *data, ++ struct tmigr_cpu *tmc) ++{ ++ __walk_groups_from(up, data, NULL, tmc->tmgroup); ++} ++ + static void walk_groups(up_f up, struct tmigr_walk *data, struct tmigr_cpu *tmc) + { + lockdep_assert_held(&tmc->lock); +@@ -1498,21 +1504,6 @@ static void tmigr_init_group(struct tmigr_group *group, unsigned int lvl, + s.seq = 0; + atomic_set(&group->migr_state, s.state); + +- /* +- * If this is a new top-level, prepare its groupmask in advance. +- * This avoids accidents where yet another new top-level is +- * created in the future and made visible before the current groupmask. +- */ +- if (list_empty(&tmigr_level_list[lvl])) { +- group->groupmask = BIT(0); +- /* +- * The previous top level has prepared its groupmask already, +- * simply account it as the first child. +- */ +- if (lvl > 0) +- group->num_children = 1; +- } +- + timerqueue_init_head(&group->events); + timerqueue_init(&group->groupevt.nextevt); + group->groupevt.nextevt.expires = KTIME_MAX; +@@ -1567,22 +1558,51 @@ static struct tmigr_group *tmigr_get_group(unsigned int cpu, int node, + return group; + } + ++static bool tmigr_init_root(struct tmigr_group *group, bool activate) ++{ ++ if (!group->parent && group != tmigr_root) { ++ /* ++ * This is the new top-level, prepare its groupmask in advance ++ * to avoid accidents where yet another new top-level is ++ * created in the future and made visible before this groupmask. ++ */ ++ group->groupmask = BIT(0); ++ WARN_ON_ONCE(activate); ++ ++ return true; ++ } ++ ++ return false; ++ ++} ++ + static void tmigr_connect_child_parent(struct tmigr_group *child, + struct tmigr_group *parent, + bool activate) + { +- struct tmigr_walk data; ++ if (tmigr_init_root(parent, activate)) { ++ /* ++ * The previous top level had prepared its groupmask already, ++ * simply account it in advance as the first child. If some groups ++ * have been created between the old and new root due to node ++ * mismatch, the new root's child will be intialized accordingly. ++ */ ++ parent->num_children = 1; ++ } + +- if (activate) { ++ /* Connecting old root to new root ? */ ++ if (!parent->parent && activate) { + /* +- * @child is the old top and @parent the new one. In this +- * case groupmask is pre-initialized and @child already +- * accounted, along with its new sibling corresponding to the +- * CPU going up. ++ * @child is the old top, or in case of node mismatch, some ++ * intermediate group between the old top and the new one in ++ * @parent. In this case the @child must be pre-accounted above ++ * as the first child. Its new inactive sibling corresponding ++ * to the CPU going up has been accounted as the second child. + */ +- WARN_ON_ONCE(child->groupmask != BIT(0) || parent->num_children != 2); ++ WARN_ON_ONCE(parent->num_children != 2); ++ child->groupmask = BIT(0); + } else { +- /* Adding @child for the CPU going up to @parent. */ ++ /* Common case adding @child for the CPU going up to @parent. */ + child->groupmask = BIT(parent->num_children++); + } + +@@ -1594,56 +1614,28 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + smp_store_release(&child->parent, parent); + + trace_tmigr_connect_child_parent(child); +- +- if (!activate) +- return; +- +- /* +- * To prevent inconsistent states, active children need to be active in +- * the new parent as well. Inactive children are already marked inactive +- * in the parent group: +- * +- * * When new groups were created by tmigr_setup_groups() starting from +- * the lowest level (and not higher then one level below the current +- * top level), then they are not active. They will be set active when +- * the new online CPU comes active. +- * +- * * But if a new group above the current top level is required, it is +- * mandatory to propagate the active state of the already existing +- * child to the new parent. So tmigr_connect_child_parent() is +- * executed with the formerly top level group (child) and the newly +- * created group (parent). +- * +- * * It is ensured that the child is active, as this setup path is +- * executed in hotplug prepare callback. This is exectued by an +- * already connected and !idle CPU. Even if all other CPUs go idle, +- * the CPU executing the setup will be responsible up to current top +- * level group. And the next time it goes inactive, it will release +- * the new childmask and parent to subsequent walkers through this +- * @child. Therefore propagate active state unconditionally. +- */ +- data.childmask = child->groupmask; +- +- /* +- * There is only one new level per time (which is protected by +- * tmigr_mutex). When connecting the child and the parent and set the +- * child active when the parent is inactive, the parent needs to be the +- * uppermost level. Otherwise there went something wrong! +- */ +- WARN_ON(!tmigr_active_up(parent, child, &data) && parent->parent); + } + +-static int tmigr_setup_groups(unsigned int cpu, unsigned int node) ++static int tmigr_setup_groups(unsigned int cpu, unsigned int node, ++ struct tmigr_group *start, bool activate) + { + struct tmigr_group *group, *child, **stack; +- int i, top = 0, err = 0; +- struct list_head *lvllist; ++ int i, top = 0, err = 0, start_lvl = 0; ++ bool root_mismatch = false; + + stack = kcalloc(tmigr_hierarchy_levels, sizeof(*stack), GFP_KERNEL); + if (!stack) + return -ENOMEM; + +- for (i = 0; i < tmigr_hierarchy_levels; i++) { ++ if (start) { ++ stack[start->level] = start; ++ start_lvl = start->level + 1; ++ } ++ ++ if (tmigr_root) ++ root_mismatch = tmigr_root->numa_node != node; ++ ++ for (i = start_lvl; i < tmigr_hierarchy_levels; i++) { + group = tmigr_get_group(cpu, node, i); + if (IS_ERR(group)) { + err = PTR_ERR(group); +@@ -1656,23 +1648,25 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + + /* + * When booting only less CPUs of a system than CPUs are +- * available, not all calculated hierarchy levels are required. ++ * available, not all calculated hierarchy levels are required, ++ * unless a node mismatch is detected. + * + * The loop is aborted as soon as the highest level, which might + * be different from tmigr_hierarchy_levels, contains only a +- * single group. ++ * single group, unless the nodes mismatch below tmigr_crossnode_level + */ +- if (group->parent || list_is_singular(&tmigr_level_list[i])) ++ if (group->parent) ++ break; ++ if ((!root_mismatch || i >= tmigr_crossnode_level) && ++ list_is_singular(&tmigr_level_list[i])) + break; + } + + /* Assert single root without parent */ + if (WARN_ON_ONCE(i >= tmigr_hierarchy_levels)) + return -EINVAL; +- if (WARN_ON_ONCE(!err && !group->parent && !list_is_singular(&tmigr_level_list[top]))) +- return -EINVAL; + +- for (; i >= 0; i--) { ++ for (; i >= start_lvl; i--) { + group = stack[i]; + + if (err < 0) { +@@ -1692,48 +1686,63 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + tmc->tmgroup = group; + tmc->groupmask = BIT(group->num_children++); + ++ tmigr_init_root(group, activate); ++ + trace_tmigr_connect_cpu_parent(tmc); + + /* There are no children that need to be connected */ + continue; + } else { + child = stack[i - 1]; +- /* Will be activated at online time */ +- tmigr_connect_child_parent(child, group, false); ++ tmigr_connect_child_parent(child, group, activate); + } ++ } + +- /* check if uppermost level was newly created */ +- if (top != i) +- continue; +- +- WARN_ON_ONCE(top == 0); ++ if (err < 0) ++ goto out; + +- lvllist = &tmigr_level_list[top]; ++ if (activate) { ++ struct tmigr_walk data; + + /* +- * Newly created root level should have accounted the upcoming +- * CPU's child group and pre-accounted the old root. ++ * To prevent inconsistent states, active children need to be active in ++ * the new parent as well. Inactive children are already marked inactive ++ * in the parent group: ++ * ++ * * When new groups were created by tmigr_setup_groups() starting from ++ * the lowest level, then they are not active. They will be set active ++ * when the new online CPU comes active. ++ * ++ * * But if new groups above the current top level are required, it is ++ * mandatory to propagate the active state of the already existing ++ * child to the new parents. So tmigr_active_up() activates the ++ * new parents while walking up from the old root to the new. ++ * ++ * * It is ensured that @start is active, as this setup path is ++ * executed in hotplug prepare callback. This is executed by an ++ * already connected and !idle CPU. Even if all other CPUs go idle, ++ * the CPU executing the setup will be responsible up to current top ++ * level group. And the next time it goes inactive, it will release ++ * the new childmask and parent to subsequent walkers through this ++ * @child. Therefore propagate active state unconditionally. + */ +- if (group->num_children == 2 && list_is_singular(lvllist)) { +- /* +- * The target CPU must never do the prepare work, except +- * on early boot when the boot CPU is the target. Otherwise +- * it may spuriously activate the old top level group inside +- * the new one (nevertheless whether old top level group is +- * active or not) and/or release an uninitialized childmask. +- */ +- WARN_ON_ONCE(cpu == raw_smp_processor_id()); +- +- lvllist = &tmigr_level_list[top - 1]; +- list_for_each_entry(child, lvllist, list) { +- if (child->parent) +- continue; ++ WARN_ON_ONCE(!start->parent); ++ data.childmask = start->groupmask; ++ __walk_groups_from(tmigr_active_up, &data, start, start->parent); ++ } + +- tmigr_connect_child_parent(child, group, true); +- } ++ /* Root update */ ++ if (list_is_singular(&tmigr_level_list[top])) { ++ group = list_first_entry(&tmigr_level_list[top], ++ typeof(*group), list); ++ WARN_ON_ONCE(group->parent); ++ if (tmigr_root) { ++ /* Old root should be the same or below */ ++ WARN_ON_ONCE(tmigr_root->level > top); + } ++ tmigr_root = group; + } +- ++out: + kfree(stack); + + return err; +@@ -1741,12 +1750,26 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + + static int tmigr_add_cpu(unsigned int cpu) + { ++ struct tmigr_group *old_root = tmigr_root; + int node = cpu_to_node(cpu); + int ret; + +- mutex_lock(&tmigr_mutex); +- ret = tmigr_setup_groups(cpu, node); +- mutex_unlock(&tmigr_mutex); ++ guard(mutex)(&tmigr_mutex); ++ ++ ret = tmigr_setup_groups(cpu, node, NULL, false); ++ ++ /* Root has changed? Connect the old one to the new */ ++ if (ret >= 0 && old_root && old_root != tmigr_root) { ++ /* ++ * The target CPU must never do the prepare work, except ++ * on early boot when the boot CPU is the target. Otherwise ++ * it may spuriously activate the old top level group inside ++ * the new one (nevertheless whether old top level group is ++ * active or not) and/or release an uninitialized childmask. ++ */ ++ WARN_ON_ONCE(cpu == raw_smp_processor_id()); ++ ret = tmigr_setup_groups(-1, old_root->numa_node, old_root, true); ++ } + + return ret; + } +-- +2.51.0 + diff --git a/queue-6.18/timers-migration-remove-locking-on-group-connection.patch b/queue-6.18/timers-migration-remove-locking-on-group-connection.patch new file mode 100644 index 0000000000..9f16f6d0d0 --- /dev/null +++ b/queue-6.18/timers-migration-remove-locking-on-group-connection.patch @@ -0,0 +1,93 @@ +From 8c45b762d3fa27f62cd2e5ac0845cff04b3fe59d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 15:25:32 +0200 +Subject: timers/migration: Remove locking on group connection + +From: Frederic Weisbecker + +[ Upstream commit fa9620355d4192200f15cb3d97c6eb9c02442249 ] + +Initializing the tmc's group, the group's number of children and the +group's parent can all be done without locking because: + + 1) Reading the group's parent and its group mask is done locklessly. + + 2) The connections prepared for a given CPU hierarchy are visible to the + target CPU once online, thanks to the CPU hotplug enforced memory + ordering. + + 3) In case of a newly created upper level, the new root and its + connections and initialization are made visible by the CPU which made + the connections. When that CPUs goes idle in the future, the new link + is published by tmigr_inactive_up() through the atomic RmW on + ->migr_state. + + 4) If CPUs were still walking up the active hierarchy, they could observe + the new root earlier. In this case the ordering is enforced by an + early initialization of the group mask and by barriers that maintain + address dependency as explained in: + + b729cc1ec21a ("timers/migration: Fix another race between hotplug and idle entry/exit") + de3ced72a792 ("timers/migration: Enforce group initialization visibility to tree walkers") + + 5) Timers are propagated by a chain of group locking from the bottom to + the top. And while doing so, the tree also propagates groups links + and initialization. Therefore remote expiration, which also relies + on group locking, will observe those links and initialization while + holding the root lock before walking the tree remotely and update + remote timers. This is especially important for migrators in the + active hierarchy that may observe the new root early. + +Therefore the locking is unnecessary at initialization. If anything, it +just brings confusion. Remove it. + +Signed-off-by: Frederic Weisbecker +Signed-off-by: Thomas Gleixner +Link: https://patch.msgid.link/20251024132536.39841-3-frederic@kernel.org +Stable-dep-of: 5eb579dfd46b ("timers/migration: Fix imbalanced NUMA trees") +Signed-off-by: Sasha Levin +--- + kernel/time/timer_migration.c | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/kernel/time/timer_migration.c b/kernel/time/timer_migration.c +index 1e371f1fdc86c..5f8aef94ca0f7 100644 +--- a/kernel/time/timer_migration.c ++++ b/kernel/time/timer_migration.c +@@ -1573,9 +1573,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + { + struct tmigr_walk data; + +- raw_spin_lock_irq(&child->lock); +- raw_spin_lock_nested(&parent->lock, SINGLE_DEPTH_NESTING); +- + if (activate) { + /* + * @child is the old top and @parent the new one. In this +@@ -1596,9 +1593,6 @@ static void tmigr_connect_child_parent(struct tmigr_group *child, + */ + smp_store_release(&child->parent, parent); + +- raw_spin_unlock(&parent->lock); +- raw_spin_unlock_irq(&child->lock); +- + trace_tmigr_connect_child_parent(child); + + if (!activate) +@@ -1695,13 +1689,9 @@ static int tmigr_setup_groups(unsigned int cpu, unsigned int node) + if (i == 0) { + struct tmigr_cpu *tmc = per_cpu_ptr(&tmigr_cpu, cpu); + +- raw_spin_lock_irq(&group->lock); +- + tmc->tmgroup = group; + tmc->groupmask = BIT(group->num_children++); + +- raw_spin_unlock_irq(&group->lock); +- + trace_tmigr_connect_cpu_parent(tmc); + + /* There are no children that need to be connected */ +-- +2.51.0 + diff --git a/queue-6.18/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch b/queue-6.18/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch new file mode 100644 index 0000000000..b220477542 --- /dev/null +++ b/queue-6.18/tools-nolibc-dirent-avoid-errno-in-readdir_r.patch @@ -0,0 +1,43 @@ +From ff3e853e56068a07aac23a92854975f38ec64fad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:51 +0200 +Subject: tools/nolibc/dirent: avoid errno in readdir_r +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit 4ada5679f18dbbe92d87c37a842c3368e6ab5e4a ] + +Using errno is not possible when NOLIBC_IGNORE_ERRNO is set. Use +sys_lseek instead of lseek as that avoids using errno. + +Fixes: 665fa8dea90d ("tools/nolibc: add support for directory access") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/dirent.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/include/nolibc/dirent.h b/tools/include/nolibc/dirent.h +index 758b95c48e7a4..61a122a60327d 100644 +--- a/tools/include/nolibc/dirent.h ++++ b/tools/include/nolibc/dirent.h +@@ -86,9 +86,9 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) + * readdir() can only return one entry at a time. + * Make sure the non-returned ones are not skipped. + */ +- ret = lseek(fd, ldir->d_off, SEEK_SET); +- if (ret == -1) +- return errno; ++ ret = sys_lseek(fd, ldir->d_off, SEEK_SET); ++ if (ret < 0) ++ return -ret; + + entry->d_ino = ldir->d_ino; + /* the destination should always be big enough */ +-- +2.51.0 + diff --git a/queue-6.18/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch b/queue-6.18/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch new file mode 100644 index 0000000000..64cb9e409e --- /dev/null +++ b/queue-6.18/tools-nolibc-handle-null-wstatus-argument-to-waitpid.patch @@ -0,0 +1,66 @@ +From aea78ec8e1ce67a5fae0cc2552ad561193ded244 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 16:26:58 +0200 +Subject: tools/nolibc: handle NULL wstatus argument to waitpid() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +[ Upstream commit 812f223fe9be03dc22abb85240b6f075135d2386 ] + +wstatus is allowed to be NULL. Avoid a segmentation fault in this case. + +Fixes: 0c89abf5ab3f ("tools/nolibc: implement waitpid() in terms of waitid()") +Signed-off-by: Thomas Weißschuh +Acked-by: Willy Tarreau +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/sys/wait.h | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/tools/include/nolibc/sys/wait.h b/tools/include/nolibc/sys/wait.h +index 4e66e1f7a03e4..9d9319ba92cbd 100644 +--- a/tools/include/nolibc/sys/wait.h ++++ b/tools/include/nolibc/sys/wait.h +@@ -65,23 +65,29 @@ pid_t waitpid(pid_t pid, int *status, int options) + + switch (info.si_code) { + case 0: +- *status = 0; ++ if (status) ++ *status = 0; + break; + case CLD_EXITED: +- *status = (info.si_status & 0xff) << 8; ++ if (status) ++ *status = (info.si_status & 0xff) << 8; + break; + case CLD_KILLED: +- *status = info.si_status & 0x7f; ++ if (status) ++ *status = info.si_status & 0x7f; + break; + case CLD_DUMPED: +- *status = (info.si_status & 0x7f) | 0x80; ++ if (status) ++ *status = (info.si_status & 0x7f) | 0x80; + break; + case CLD_STOPPED: + case CLD_TRAPPED: +- *status = (info.si_status << 8) + 0x7f; ++ if (status) ++ *status = (info.si_status << 8) + 0x7f; + break; + case CLD_CONTINUED: +- *status = 0xffff; ++ if (status) ++ *status = 0xffff; + break; + default: + return -1; +-- +2.51.0 + diff --git a/queue-6.18/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch b/queue-6.18/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch new file mode 100644 index 0000000000..057a12315c --- /dev/null +++ b/queue-6.18/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch @@ -0,0 +1,43 @@ +From fc85e931b84ca49dcc5972bd873d5e1f7c3bc335 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:50 +0200 +Subject: tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit c485ca3aff2442adea4c08ceb5183e671ebed22a ] + +There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, +simply print the message with "unknown error" rather than the integer +value of errno. + +Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/stdio.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h +index 7630234408c58..724d05ce69624 100644 +--- a/tools/include/nolibc/stdio.h ++++ b/tools/include/nolibc/stdio.h +@@ -600,7 +600,11 @@ int sscanf(const char *str, const char *format, ...) + static __attribute__((unused)) + void perror(const char *msg) + { ++#ifdef NOLIBC_IGNORE_ERRNO ++ fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); ++#else + fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); ++#endif + } + + static __attribute__((unused)) +-- +2.51.0 + diff --git a/queue-6.18/tools-nolibc-x86-fix-section-mismatch-caused-by-asm-.patch b/queue-6.18/tools-nolibc-x86-fix-section-mismatch-caused-by-asm-.patch new file mode 100644 index 0000000000..83d1c1a33d --- /dev/null +++ b/queue-6.18/tools-nolibc-x86-fix-section-mismatch-caused-by-asm-.patch @@ -0,0 +1,147 @@ +From d49e69a38714114fff83b22f3efe4e0903b61fff Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:24:57 +0100 +Subject: tools/nolibc: x86: fix section mismatch caused by asm "mem*" + functions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Willy Tarreau + +[ Upstream commit 2602949b22330f1275138e2b5aea5d49126b9757 ] + +I recently got occasional build failures at -Os or -Oz that would always +involve waitpid(), where the assembler would complain about this: + + init.s: Error: .size expression for waitpid.constprop.0 does not evaluate to a constant + +And without -fno-asynchronous-unwind-tables it could also spit such +errors: + + init.s:836: Error: CFI instruction used without previous .cfi_startproc + init.s:838: Error: .cfi_endproc without corresponding .cfi_startproc + init.s: Error: open CFI at the end of file; missing .cfi_endproc directive + +A trimmed down reproducer is as simple as this: + + int main(int argc, char **argv) + { + int ret, status; + + if (argc == 0) + ret = waitpid(-1, &status, 0); + else + ret = waitpid(-1, &status, 0); + + return status; + } + +It produces the following asm code on x86_64: + + .text + .section .text.nolibc_memmove_memcpy + .weak memmove + .weak memcpy + memmove: + memcpy: + movq %rdx, %rcx + (...) + retq + .section .text.nolibc_memset + .weak memset + memset: + xchgl %eax, %esi + movq %rdx, %rcx + pushq %rdi + rep stosb + popq %rax + retq + + .type waitpid.constprop.0.isra.0, @function + waitpid.constprop.0.isra.0: + subq $8, %rsp + (...) + jmp *.L5(,%rax,8) + .section .rodata + .align 8 + .align 4 + .L5: + .quad .L10 + (...) + .quad .L4 + .text + .L10: + (...) + .cfi_def_cfa_offset 8 + ret + .cfi_endproc + .LFE273: + .size waitpid.constprop.0.isra.0, .-waitpid.constprop.0.isra.0 + +It's a bit dense, but here's the explanation: the compiler has emitted a +".text" statement because it knows it's working in the .text section. + +Then, our hand-written asm code for the mem* functions forced the section +to .text.something without the compiler knowing about it, so it thinks +the code is still being emitted for .text. As such, without any .section +statement, the waitpid.constprop.0.isra.0 label is in fact placed in the +previously created section, here .text.nolibc_memset. + +The waitpid() function involves a switch/case statement that can be +turned to a jump table, which is what the compiler does with the .rodata +section, and after that it restores .text, which is no longer the +previous .text.nolibc_memset section. Then the CFI statements cross a +section, so does the .size calculation, which explains the error. + +While a first approach consisting in placing an explicit ".text" at the +end of these functions was verified to work, it's still unreliable as +it depends on what the compiler remembers having emitted previously. A +better approach is to replace the ".section" with ".pushsection", and +place a ".popsection" at the end, so that these code blocks are agnostic +to where they're placed relative to other blocks. + +Fixes: 553845eebd60 ("tools/nolibc: x86-64: Use `rep movsb` for `memcpy()` and `memmove()`") +Fixes: 12108aa8c1a1 ("tools/nolibc: x86-64: Use `rep stosb` for `memset()`") +Signed-off-by: Willy Tarreau +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/arch-x86.h | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h +index d3efc0c3b8adc..c8b0c3e624a51 100644 +--- a/tools/include/nolibc/arch-x86.h ++++ b/tools/include/nolibc/arch-x86.h +@@ -351,7 +351,7 @@ void *memcpy(void *dst, const void *src, size_t len); + void *memset(void *dst, int c, size_t len); + + __asm__ ( +-".section .text.nolibc_memmove_memcpy\n" ++".pushsection .text.nolibc_memmove_memcpy\n" + ".weak memmove\n" + ".weak memcpy\n" + "memmove:\n" +@@ -371,8 +371,9 @@ __asm__ ( + "rep movsb\n\t" + "cld\n\t" + "retq\n" ++".popsection\n" + +-".section .text.nolibc_memset\n" ++".pushsection .text.nolibc_memset\n" + ".weak memset\n" + "memset:\n" + "xchgl %eax, %esi\n\t" +@@ -381,6 +382,7 @@ __asm__ ( + "rep stosb\n\t" + "popq %rax\n\t" + "retq\n" ++".popsection\n" + ); + + #endif /* !defined(__x86_64__) */ +-- +2.51.0 + diff --git a/queue-6.18/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch b/queue-6.18/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch new file mode 100644 index 0000000000..05e214aaaf --- /dev/null +++ b/queue-6.18/tools-power-turbostat-regression-fix-uncore-mhz-prin.patch @@ -0,0 +1,77 @@ +From 0df1a19a424a9f623c6c6467c8b298fc331428a7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 18:41:38 -0300 +Subject: tools/power turbostat: Regression fix Uncore MHz printed in hex + +From: Len Brown + +[ Upstream commit 92664f2e6ab2228a3330734fc72dabeaf8a49ee1 ] + +A patch to allow specifying FORMAT_AVERAGE to added counters... +broke the internally added counter for Cluster Uncore MHz -- printing it in HEX. + +Fixes: dcd1c379b0f1 ("tools/power turbostat: add format "average" for external attributes") +Reported-by: Andrej Tkalcec +Signed-off-by: Len Brown +Signed-off-by: Sasha Levin +--- + tools/power/x86/turbostat/turbostat.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c +index f2512d78bcbd8..1b5ca2f4e92ff 100644 +--- a/tools/power/x86/turbostat/turbostat.c ++++ b/tools/power/x86/turbostat/turbostat.c +@@ -3285,13 +3285,13 @@ int format_counters(PER_THREAD_PARAMS) + + /* Added counters */ + for (i = 0, mp = sys.tp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)t->counter[i]); + else + outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), t->counter[i]); +- } else if (mp->format == FORMAT_DELTA) { ++ } else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) { + if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns) + outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), t->counter[i]); + else +@@ -3382,13 +3382,13 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%lld", (printed++ ? delim : ""), c->core_throt_cnt); + + for (i = 0, mp = sys.cp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)c->counter[i]); + else + outp += sprintf(outp, "%s0x%016llx", (printed++ ? delim : ""), c->counter[i]); +- } else if (mp->format == FORMAT_DELTA) { ++ } else if (mp->format == FORMAT_DELTA || mp->format == FORMAT_AVERAGE) { + if ((mp->type == COUNTER_ITEMS) && sums_need_wide_columns) + outp += sprintf(outp, "%s%8lld", (printed++ ? delim : ""), c->counter[i]); + else +@@ -3581,7 +3581,7 @@ int format_counters(PER_THREAD_PARAMS) + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), p->uncore_mhz); + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) { ++ if (mp->format == FORMAT_RAW) { + if (mp->width == 32) + outp += + sprintf(outp, "%s0x%08x", (printed++ ? delim : ""), (unsigned int)p->counter[i]); +@@ -3758,7 +3758,7 @@ int delta_package(struct pkg_data *new, struct pkg_data *old) + new->rapl_dram_perf_status.raw_value - old->rapl_dram_perf_status.raw_value; + + for (i = 0, mp = sys.pp; mp; i++, mp = mp->next) { +- if (mp->format == FORMAT_RAW || mp->format == FORMAT_AVERAGE) ++ if (mp->format == FORMAT_RAW) + old->counter[i] = new->counter[i]; + else if (mp->format == FORMAT_AVERAGE) + old->counter[i] = new->counter[i]; +-- +2.51.0 + diff --git a/queue-6.18/tools-rtla-fix-on-threshold-always-triggering.patch b/queue-6.18/tools-rtla-fix-on-threshold-always-triggering.patch new file mode 100644 index 0000000000..df49c38e76 --- /dev/null +++ b/queue-6.18/tools-rtla-fix-on-threshold-always-triggering.patch @@ -0,0 +1,86 @@ +From ab273989c750cd3706708094c23292decef6ae31 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 11:53:39 +0200 +Subject: tools/rtla: Fix --on-threshold always triggering + +From: Tomas Glozar + +[ Upstream commit 417bd0d502f90a2e785e7299dae4f248b5ac0292 ] + +Commit 8d933d5c89e8 ("rtla/timerlat: Add continue action") moved the +code performing on-threshold actions (enabled through --on-threshold +option) to inside the RTLA main loop. + +The condition in the loop does not check whether the threshold was +actually exceeded or if stop tracing was requested by the user through +SIGINT or duration. This leads to a bug where on-threshold actions are +always performed, even when the threshold was not hit. + +(BPF mode is not affected, since it uses a different condition in the +while loop.) + +Add a condition that checks for !stop_tracing before executing the +actions. Also, fix incorrect brackets in hist_main_loop to match the +semantics of top_main_loop. + +Fixes: 8d933d5c89e8 ("rtla/timerlat: Add continue action") +Fixes: 2f3172f9dd58 ("tools/rtla: Consolidate code between osnoise/timerlat and hist/top") +Reviewed-by: Crystal Wood +Reviewed-by: Wander Lairson Costa +Link: https://lore.kernel.org/r/20251007095341.186923-1-tglozar@redhat.com +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/src/common.c | 24 +++++++++++++++--------- + 1 file changed, 15 insertions(+), 9 deletions(-) + +diff --git a/tools/tracing/rtla/src/common.c b/tools/tracing/rtla/src/common.c +index 2e6e3dac1897f..b197037fc58b3 100644 +--- a/tools/tracing/rtla/src/common.c ++++ b/tools/tracing/rtla/src/common.c +@@ -268,6 +268,10 @@ int top_main_loop(struct osnoise_tool *tool) + tool->ops->print_stats(tool); + + if (osnoise_trace_is_off(tool, record)) { ++ if (stop_tracing) ++ /* stop tracing requested, do not perform actions */ ++ return 0; ++ + actions_perform(¶ms->threshold_actions); + + if (!params->threshold_actions.continue_flag) +@@ -315,20 +319,22 @@ int hist_main_loop(struct osnoise_tool *tool) + } + + if (osnoise_trace_is_off(tool, tool->record)) { ++ if (stop_tracing) ++ /* stop tracing requested, do not perform actions */ ++ break; ++ + actions_perform(¶ms->threshold_actions); + +- if (!params->threshold_actions.continue_flag) { ++ if (!params->threshold_actions.continue_flag) + /* continue flag not set, break */ + break; + +- /* continue action reached, re-enable tracing */ +- if (tool->record) +- trace_instance_start(&tool->record->trace); +- if (tool->aa) +- trace_instance_start(&tool->aa->trace); +- trace_instance_start(&tool->trace); +- } +- break; ++ /* continue action reached, re-enable tracing */ ++ if (tool->record) ++ trace_instance_start(&tool->record->trace); ++ if (tool->aa) ++ trace_instance_start(&tool->aa->trace); ++ trace_instance_start(&tool->trace); + } + + /* is there still any user-threads ? */ +-- +2.51.0 + diff --git a/queue-6.18/tools-rtla-fix-unassigned-nr_cpus.patch b/queue-6.18/tools-rtla-fix-unassigned-nr_cpus.patch new file mode 100644 index 0000000000..8cf25d1b4a --- /dev/null +++ b/queue-6.18/tools-rtla-fix-unassigned-nr_cpus.patch @@ -0,0 +1,57 @@ +From 810cf42f248ce71a46553d74ad696d63ceea9fdd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 20:08:45 +0300 +Subject: tools/rtla: Fix unassigned nr_cpus + +From: Costa Shulyupin + +[ Upstream commit b4275b23010df719ec6508ddbc84951dcd24adce ] + +In recently introduced timerlat_free(), +the variable 'nr_cpus' is not assigned. + +Assign it with sysconf(_SC_NPROCESSORS_CONF) as done elsewhere. +Remove the culprit: -Wno-maybe-uninitialized. The rest of the +code is clean. + +Signed-off-by: Costa Shulyupin +Reviewed-by: Tomas Glozar +Fixes: 2f3172f9dd58 ("tools/rtla: Consolidate code between osnoise/timerlat and hist/top") +Link: https://lore.kernel.org/r/20251002170846.437888-1-costa.shul@redhat.com +Signed-off-by: Tomas Glozar +Signed-off-by: Sasha Levin +--- + tools/tracing/rtla/Makefile.rtla | 2 +- + tools/tracing/rtla/src/timerlat.c | 3 ++- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/tools/tracing/rtla/Makefile.rtla b/tools/tracing/rtla/Makefile.rtla +index 08c1b40883d3a..1743d91829d46 100644 +--- a/tools/tracing/rtla/Makefile.rtla ++++ b/tools/tracing/rtla/Makefile.rtla +@@ -18,7 +18,7 @@ export CC AR STRIP PKG_CONFIG LD_SO_CONF_PATH LDCONFIG + FOPTS := -flto=auto -ffat-lto-objects -fexceptions -fstack-protector-strong \ + -fasynchronous-unwind-tables -fstack-clash-protection + WOPTS := -O -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 \ +- -Wp,-D_GLIBCXX_ASSERTIONS -Wno-maybe-uninitialized ++ -Wp,-D_GLIBCXX_ASSERTIONS + + ifeq ($(CC),clang) + FOPTS := $(filter-out -flto=auto -ffat-lto-objects, $(FOPTS)) +diff --git a/tools/tracing/rtla/src/timerlat.c b/tools/tracing/rtla/src/timerlat.c +index b692128741279..11ad447a8dd78 100644 +--- a/tools/tracing/rtla/src/timerlat.c ++++ b/tools/tracing/rtla/src/timerlat.c +@@ -215,7 +215,8 @@ void timerlat_analyze(struct osnoise_tool *tool, bool stopped) + void timerlat_free(struct osnoise_tool *tool) + { + struct timerlat_params *params = to_timerlat_params(tool->params); +- int nr_cpus, i; ++ int nr_cpus = sysconf(_SC_NPROCESSORS_CONF); ++ int i; + + timerlat_aa_destroy(); + if (dma_latency_fd >= 0) +-- +2.51.0 + diff --git a/queue-6.18/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch b/queue-6.18/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch new file mode 100644 index 0000000000..a09cbb1aa2 --- /dev/null +++ b/queue-6.18/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch @@ -0,0 +1,45 @@ +From 10c32b6fff758b789e03715ad627813839ccf65e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 18:13:48 -0400 +Subject: tracefs: fix a leak in eventfs_create_events_dir() + +From: Al Viro + +[ Upstream commit 798a401660a151633cb171738a72a8f1efb9b0b4 ] + +If we have LOCKDOWN_TRACEFS, the function bails out - *after* +having locked the parent directory and without bothering to +undo that. Just check it before tracefs_start_creating()... + +Fixes: e24709454c45 "tracefs/eventfs: Add missing lockdown checks" +Acked-by: Steven Rostedt (Google) +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/tracefs/event_inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index 8705c77a9e75a..93c231601c8e2 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -757,7 +757,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + const struct eventfs_entry *entries, + int size, void *data) + { +- struct dentry *dentry = tracefs_start_creating(name, parent); ++ struct dentry *dentry; + struct eventfs_root_inode *rei; + struct eventfs_inode *ei; + struct tracefs_inode *ti; +@@ -768,6 +768,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + ++ dentry = tracefs_start_creating(name, parent); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + +-- +2.51.0 + diff --git a/queue-6.18/tty-serial-imx-only-configure-the-wake-register-when.patch b/queue-6.18/tty-serial-imx-only-configure-the-wake-register-when.patch new file mode 100644 index 0000000000..f985b2da1b --- /dev/null +++ b/queue-6.18/tty-serial-imx-only-configure-the-wake-register-when.patch @@ -0,0 +1,56 @@ +From ce1ea46ee834631642af5f3e21108422985f996a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 12:52:58 +0800 +Subject: tty: serial: imx: Only configure the wake register when device is set + as wakeup source + +From: Sherry Sun + +[ Upstream commit d55f3d2375ceeb08330d30f1e08196993c0b6583 ] + +Currently, the i.MX UART driver enables wake-related registers for all +UART devices by default. However, this is unnecessary for devices that +are not configured as wakeup sources. To address this, add a +device_may_wakeup() check before configuring the UART wake-related +registers. + +Fixes: db1a9b55004c ("tty: serial: imx: Allow UART to be a source for wakeup") +Signed-off-by: Sherry Sun +Reviewed-by: Frank Li +Link: https://patch.msgid.link/20251002045259.2725461-2-sherry.sun@nxp.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/tty/serial/imx.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c +index 500dfc009d03e..90e2ea1e8afe5 100644 +--- a/drivers/tty/serial/imx.c ++++ b/drivers/tty/serial/imx.c +@@ -2697,8 +2697,22 @@ static void imx_uart_save_context(struct imx_port *sport) + /* called with irq off */ + static void imx_uart_enable_wakeup(struct imx_port *sport, bool on) + { ++ struct tty_port *port = &sport->port.state->port; ++ struct device *tty_dev; ++ bool may_wake = false; + u32 ucr3; + ++ scoped_guard(tty_port_tty, port) { ++ struct tty_struct *tty = scoped_tty(); ++ ++ tty_dev = tty->dev; ++ may_wake = tty_dev && device_may_wakeup(tty_dev); ++ } ++ ++ /* only configure the wake register when device set as wakeup source */ ++ if (!may_wake) ++ return; ++ + uart_port_lock_irq(&sport->port); + + ucr3 = imx_uart_readl(sport, UCR3); +-- +2.51.0 + diff --git a/queue-6.18/ublk-prevent-invalid-access-with-debug.patch b/queue-6.18/ublk-prevent-invalid-access-with-debug.patch new file mode 100644 index 0000000000..e4a6fa5bb3 --- /dev/null +++ b/queue-6.18/ublk-prevent-invalid-access-with-debug.patch @@ -0,0 +1,57 @@ +From 4c086d6d194e1de330569ff0a48e38cc92844762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 12:48:35 +0000 +Subject: ublk: prevent invalid access with DEBUG + +From: Kevin Brodsky + +[ Upstream commit c6a45ee7607de3a350008630f4369b1b5ac80884 ] + +ublk_ch_uring_cmd_local() may jump to the out label before +initialising the io pointer. This will cause trouble if DEBUG is +defined, because the pr_devel() call dereferences io. Clang reports: + +drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] + 2403 | if (tag >= ub->dev_info.queue_depth) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here + 2492 | __func__, cmd_op, tag, ret, io->flags); + | + +Fix this by initialising io to NULL and checking it before +dereferencing it. + +Signed-off-by: Kevin Brodsky +Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") +Reviewed-by: Caleb Sander Mateos +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index 0c74a41a67530..359564c40cb50 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -2367,7 +2367,7 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, + u16 buf_idx = UBLK_INVALID_BUF_IDX; + struct ublk_device *ub = cmd->file->private_data; + struct ublk_queue *ubq; +- struct ublk_io *io; ++ struct ublk_io *io = NULL; + u32 cmd_op = cmd->cmd_op; + u16 q_id = READ_ONCE(ub_src->q_id); + u16 tag = READ_ONCE(ub_src->tag); +@@ -2488,7 +2488,7 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, + + out: + pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", +- __func__, cmd_op, tag, ret, io->flags); ++ __func__, cmd_op, tag, ret, io ? io->flags : 0); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.18/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-6.18/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..53f6609fba --- /dev/null +++ b/queue-6.18/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From 979adf7ebc2d8c2a7d1373e1e901f37c7842048e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 81454c3e2484c..338dd2aaabc87 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-6.18/um-disable-kasan_inline-when-static_link-is-selected.patch b/queue-6.18/um-disable-kasan_inline-when-static_link-is-selected.patch new file mode 100644 index 0000000000..59def1439a --- /dev/null +++ b/queue-6.18/um-disable-kasan_inline-when-static_link-is-selected.patch @@ -0,0 +1,56 @@ +From a04f67295f7c388b917c8820369a74998d0d844f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Nov 2025 10:56:02 +0100 +Subject: um: Disable KASAN_INLINE when STATIC_LINK is selected + +From: Christophe Leroy (CS GROUP) + +[ Upstream commit a3209bb94b36351f11e0d9e72ac44e5dd777a069 ] + +um doesn't support KASAN_INLINE together with STATIC_LINK. + +Instead of failing the build, disable KASAN_INLINE when +STATIC_LINK is selected. + +Reported-by: kernel test robot +Closes: https://lore.kernel.org/oe-kbuild-all/202511290451.x9GZVJ1l-lkp@intel.com/ +Fixes: 1e338f4d99e6 ("kasan: introduce ARCH_DEFER_KASAN and unify static key across modes") +Signed-off-by: Christophe Leroy (CS GROUP) +Link: https://patch.msgid.link/2620ab0bbba640b6237c50b9c0dca1c7d1142f5d.1764410067.git.chleroy@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/Kconfig | 1 + + arch/um/include/asm/kasan.h | 4 ---- + 2 files changed, 1 insertion(+), 4 deletions(-) + +diff --git a/arch/um/Kconfig b/arch/um/Kconfig +index 49781bee79058..93ed850d508ed 100644 +--- a/arch/um/Kconfig ++++ b/arch/um/Kconfig +@@ -5,6 +5,7 @@ menu "UML-specific options" + config UML + bool + default y ++ select ARCH_DISABLE_KASAN_INLINE if STATIC_LINK + select ARCH_NEEDS_DEFER_KASAN if STATIC_LINK + select ARCH_WANTS_DYNAMIC_TASK_STRUCT + select ARCH_HAS_CACHE_LINE_SIZE +diff --git a/arch/um/include/asm/kasan.h b/arch/um/include/asm/kasan.h +index b54a4e937fd12..81bcdc0f962e6 100644 +--- a/arch/um/include/asm/kasan.h ++++ b/arch/um/include/asm/kasan.h +@@ -24,10 +24,6 @@ + + #ifdef CONFIG_KASAN + void kasan_init(void); +- +-#if defined(CONFIG_STATIC_LINK) && defined(CONFIG_KASAN_INLINE) +-#error UML does not work in KASAN_INLINE mode with STATIC_LINK enabled! +-#endif + #else + static inline void kasan_init(void) { } + #endif /* CONFIG_KASAN */ +-- +2.51.0 + diff --git a/queue-6.18/um-don-t-rename-vmap-to-kernel_vmap.patch b/queue-6.18/um-don-t-rename-vmap-to-kernel_vmap.patch new file mode 100644 index 0000000000..ebf12d5bf2 --- /dev/null +++ b/queue-6.18/um-don-t-rename-vmap-to-kernel_vmap.patch @@ -0,0 +1,70 @@ +From 9655830757e79ef356e6529aa345eb810206175e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 22 Nov 2025 16:32:12 +0800 +Subject: um: Don't rename vmap to kernel_vmap + +From: David Gow + +[ Upstream commit a74b6c0e53a6df8e8a096b50c06c4f872906368a ] + +In order to work around the existence of a vmap symbol in libpcap, the +UML makefile unconditionally redefines vmap to kernel_vmap. However, +this not only affects the actual vmap symbol, but also anything else +named vmap, including a number of struct members in DRM. + +This would not be too much of a problem, since all uses are also +updated, except we now have Rust DRM bindings, which expect the +corresponding Rust structs to have 'vmap' names. Since the redefinition +applies in bindgen, but not to Rust code, we end up with errors such as: + +error[E0560]: struct `drm_gem_object_funcs` has no fields named `vmap` + --> rust/kernel/drm/gem/mod.rs:210:9 + +Since libpcap support was removed in commit 12b8e7e69aa7 ("um: Remove +obsolete pcap driver"), remove the, now unnecessary, define as well. + +We also take this opportunity to update the comment. + +Signed-off-by: David Gow +Acked-by: Miguel Ojeda +Link: https://patch.msgid.link/20251122083213.3996586-1-davidgow@google.com +Fixes: 12b8e7e69aa7 ("um: Remove obsolete pcap driver") +[adjust commmit message a bit] +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + arch/um/Makefile | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/arch/um/Makefile b/arch/um/Makefile +index 7be0143b5ba35..721b652ffb658 100644 +--- a/arch/um/Makefile ++++ b/arch/um/Makefile +@@ -46,19 +46,17 @@ ARCH_INCLUDE := -I$(srctree)/$(SHARED_HEADERS) + ARCH_INCLUDE += -I$(srctree)/$(HOST_DIR)/um/shared + KBUILD_CPPFLAGS += -I$(srctree)/$(HOST_DIR)/um + +-# -Dvmap=kernel_vmap prevents anything from referencing the libpcap.o symbol so +-# named - it's a common symbol in libpcap, so we get a binary which crashes. +-# +-# Same things for in6addr_loopback and mktime - found in libc. For these two we +-# only get link-time error, luckily. ++# -Dstrrchr=kernel_strrchr (as well as the various in6addr symbols) prevents ++# anything from referencing ++# libc symbols with the same name, which can cause a linker error. + # + # -Dlongjmp=kernel_longjmp prevents anything from referencing the libpthread.a + # embedded copy of longjmp, same thing for setjmp. + # +-# These apply to USER_CFLAGS to. ++# These apply to USER_CFLAGS too. + + KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \ +- $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ ++ $(ARCH_INCLUDE) $(MODE_INCLUDE) \ + -Dlongjmp=kernel_longjmp -Dsetjmp=kernel_setjmp \ + -Din6addr_loopback=kernel_in6addr_loopback \ + -Din6addr_any=kernel_in6addr_any -Dstrrchr=kernel_strrchr \ +-- +2.51.0 + diff --git a/queue-6.18/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-6.18/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..ad38ea39be --- /dev/null +++ b/queue-6.18/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From 1f87d81a42ad8b428f520d7abb58767d0a8002d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 225863321dc47..45cff32656c6e 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-6.18/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-6.18/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..fa0cce9b9c --- /dev/null +++ b/queue-6.18/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From ee2f073c8322b9fb9da0bbc0dd5c09ceb59e0ff6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 3f83ecc9fc236..b07bdf16326a4 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-6.18/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-6.18/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..e3d7e846a5 --- /dev/null +++ b/queue-6.18/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From 05a8a0dc2c5384abdaf39a68a504f94ff989484f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index b07bdf16326a4..ef0d730770347 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -728,6 +732,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-6.18/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-6.18/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..d7d4849164 --- /dev/null +++ b/queue-6.18/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From 4453dc3591cf3273154f1caf391c6e234514028c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index d2b2787be4092..6138468c67c47 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2431,7 +2431,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-6.18/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-6.18/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..ba3a0dd95c --- /dev/null +++ b/queue-6.18/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 4204637a3ec55e8fb94de3464a865e217cc1fdef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index b71680c58de6c..46f343ba48b3d 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -40,6 +40,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -667,6 +668,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-6.18/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch b/queue-6.18/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch new file mode 100644 index 0000000000..087277cf46 --- /dev/null +++ b/queue-6.18/vdpa-mlx5-fix-incorrect-error-code-reporting-in-quer.patch @@ -0,0 +1,49 @@ +From ebc927a919174e09df90171ba41a6efdbd814652 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 06:42:53 -0700 +Subject: vdpa/mlx5: Fix incorrect error code reporting in query_virtqueues + +From: Alok Tiwari + +[ Upstream commit f0ea2e91093ac979d07ebd033e0f45869b1d2608 ] + +When query_virtqueues() fails, the error log prints the variable err +instead of cmd->err. Since err may still be zero at this point, the +log message can misleadingly report a success value 0 even though the +command actually failed. + +Even worse, once err is set to the first failure, subsequent logs +print that same stale value. This makes the error reporting appear +one step behind the actual failing queue index, which is confusing +and misleading. + +Fix the log to report cmd->err, which reflects the real failure code +returned by the firmware. + +Fixes: 1fcdf43ea69e ("vdpa/mlx5: Use async API for vq query command") +Signed-off-by: Alok Tiwari +Acked-by: Jason Wang +Reviewed-by: Dragos Tatulea +Signed-off-by: Michael S. Tsirkin +Message-Id: <20250929134258.80956-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/mlx5/net/mlx5_vnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c +index a7936bd1aabe1..ddaa1366704bb 100644 +--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c ++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c +@@ -1256,7 +1256,7 @@ static int query_virtqueues(struct mlx5_vdpa_net *ndev, + int vq_idx = start_vq + i; + + if (cmd->err) { +- mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, err); ++ mlx5_vdpa_err(mvdev, "query vq %d failed, err: %d\n", vq_idx, cmd->err); + if (!err) + err = cmd->err; + continue; +-- +2.51.0 + diff --git a/queue-6.18/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch b/queue-6.18/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch new file mode 100644 index 0000000000..dff9dae9a1 --- /dev/null +++ b/queue-6.18/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch @@ -0,0 +1,40 @@ +From 09cfb09050e08f4c2458cba1c0a2069daa1ddfa8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 10:46:46 -0700 +Subject: vdpa/pds: use %pe for ERR_PTR() in event handler registration + +From: Alok Tiwari + +[ Upstream commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 ] + +Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended +for string pointers, while %pe correctly prints symbolic error names +for error pointers returned via ERR_PTR(). +This shows the returned error value more clearly. + +Fixes: 67f27b8b3a34 ("pds_vdpa: subscribe to the pds_core events") +Signed-off-by: Alok Tiwari +Reviewed-by: Brett Creeley +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251018174705.1511982-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/pds/vdpa_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c +index 36f61cc96e211..43426bd971acc 100644 +--- a/drivers/vdpa/pds/vdpa_dev.c ++++ b/drivers/vdpa/pds/vdpa_dev.c +@@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) + err = pdsc_register_notify(nb); + if (err) { + nb->notifier_call = NULL; +- dev_err(dev, "failed to register pds event handler: %ps\n", ++ dev_err(dev, "failed to register pds event handler: %pe\n", + ERR_PTR(err)); + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.18/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch b/queue-6.18/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch new file mode 100644 index 0000000000..50bbe449a2 --- /dev/null +++ b/queue-6.18/vfio-pci-use-rcu-for-error-request-triggers-to-avoid.patch @@ -0,0 +1,305 @@ +From 7876a442ff6263a82b3f56fa55006898401b4a67 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 15:36:22 -0700 +Subject: vfio/pci: Use RCU for error/request triggers to avoid circular + locking + +From: Alex Williamson + +[ Upstream commit 98693e0897f754e3f51ce6626ed5f785f625ba2b ] + +Thanks to a device generating an ACS violation during bus reset, +lockdep reported the following circular locking issue: + +CPU0: SET_IRQS (MSI/X): holds igate, acquires memory_lock +CPU1: HOT_RESET: holds memory_lock, acquires pci_bus_sem +CPU2: AER: holds pci_bus_sem, acquires igate + +This results in a potential 3-way deadlock. + +Remove the pci_bus_sem->igate leg of the triangle by using RCU +to peek at the eventfd rather than locking it with igate. + +Fixes: 3be3a074cf5b ("vfio-pci: Don't use device_lock around AER interrupt setup") +Signed-off-by: Alex Williamson +Reviewed-by: Jason Gunthorpe +Link: https://lore.kernel.org/r/20251124223623.2770706-1-alex@shazbot.org +Signed-off-by: Alex Williamson +Signed-off-by: Sasha Levin +--- + drivers/vfio/pci/vfio_pci_core.c | 68 ++++++++++++++++++++++--------- + drivers/vfio/pci/vfio_pci_intrs.c | 52 ++++++++++++++--------- + drivers/vfio/pci/vfio_pci_priv.h | 4 ++ + include/linux/vfio_pci_core.h | 10 ++++- + 4 files changed, 93 insertions(+), 41 deletions(-) + +diff --git a/drivers/vfio/pci/vfio_pci_core.c b/drivers/vfio/pci/vfio_pci_core.c +index 7dcf5439dedc9..5efe7535f41ed 100644 +--- a/drivers/vfio/pci/vfio_pci_core.c ++++ b/drivers/vfio/pci/vfio_pci_core.c +@@ -41,6 +41,40 @@ static bool nointxmask; + static bool disable_vga; + static bool disable_idle_d3; + ++static void vfio_pci_eventfd_rcu_free(struct rcu_head *rcu) ++{ ++ struct vfio_pci_eventfd *eventfd = ++ container_of(rcu, struct vfio_pci_eventfd, rcu); ++ ++ eventfd_ctx_put(eventfd->ctx); ++ kfree(eventfd); ++} ++ ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx) ++{ ++ struct vfio_pci_eventfd *new = NULL; ++ struct vfio_pci_eventfd *old; ++ ++ lockdep_assert_held(&vdev->igate); ++ ++ if (ctx) { ++ new = kzalloc(sizeof(*new), GFP_KERNEL_ACCOUNT); ++ if (!new) ++ return -ENOMEM; ++ ++ new->ctx = ctx; ++ } ++ ++ old = rcu_replace_pointer(*peventfd, new, ++ lockdep_is_held(&vdev->igate)); ++ if (old) ++ call_rcu(&old->rcu, vfio_pci_eventfd_rcu_free); ++ ++ return 0; ++} ++ + /* List of PF's that vfio_pci_core_sriov_configure() has been called on */ + static DEFINE_MUTEX(vfio_pci_sriov_pfs_mutex); + static LIST_HEAD(vfio_pci_sriov_pfs); +@@ -696,14 +730,8 @@ void vfio_pci_core_close_device(struct vfio_device *core_vdev) + vfio_pci_core_disable(vdev); + + mutex_lock(&vdev->igate); +- if (vdev->err_trigger) { +- eventfd_ctx_put(vdev->err_trigger); +- vdev->err_trigger = NULL; +- } +- if (vdev->req_trigger) { +- eventfd_ctx_put(vdev->req_trigger); +- vdev->req_trigger = NULL; +- } ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->err_trigger, NULL); ++ vfio_pci_eventfd_replace_locked(vdev, &vdev->req_trigger, NULL); + mutex_unlock(&vdev->igate); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_close_device); +@@ -1800,21 +1828,21 @@ void vfio_pci_core_request(struct vfio_device *core_vdev, unsigned int count) + struct vfio_pci_core_device *vdev = + container_of(core_vdev, struct vfio_pci_core_device, vdev); + struct pci_dev *pdev = vdev->pdev; ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->req_trigger) { ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->req_trigger); ++ if (eventfd) { + if (!(count % 10)) + pci_notice_ratelimited(pdev, + "Relaying device request to user (#%u)\n", + count); +- eventfd_signal(vdev->req_trigger); ++ eventfd_signal(eventfd->ctx); + } else if (count == 0) { + pci_warn(pdev, + "No device request channel registered, blocked until released by user\n"); + } +- +- mutex_unlock(&vdev->igate); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL_GPL(vfio_pci_core_request); + +@@ -2227,13 +2255,13 @@ pci_ers_result_t vfio_pci_core_aer_err_detected(struct pci_dev *pdev, + pci_channel_state_t state) + { + struct vfio_pci_core_device *vdev = dev_get_drvdata(&pdev->dev); ++ struct vfio_pci_eventfd *eventfd; + +- mutex_lock(&vdev->igate); +- +- if (vdev->err_trigger) +- eventfd_signal(vdev->err_trigger); +- +- mutex_unlock(&vdev->igate); ++ rcu_read_lock(); ++ eventfd = rcu_dereference(vdev->err_trigger); ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ rcu_read_unlock(); + + return PCI_ERS_RESULT_CAN_RECOVER; + } +diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c +index 30d3e921cb0de..c76e753b3cecd 100644 +--- a/drivers/vfio/pci/vfio_pci_intrs.c ++++ b/drivers/vfio/pci/vfio_pci_intrs.c +@@ -731,21 +731,27 @@ static int vfio_pci_set_msi_trigger(struct vfio_pci_core_device *vdev, + return 0; + } + +-static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, ++static int vfio_pci_set_ctx_trigger_single(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, + unsigned int count, uint32_t flags, + void *data) + { + /* DATA_NONE/DATA_BOOL enables loopback testing */ + if (flags & VFIO_IRQ_SET_DATA_NONE) { +- if (*ctx) { +- if (count) { +- eventfd_signal(*ctx); +- } else { +- eventfd_ctx_put(*ctx); +- *ctx = NULL; +- } ++ struct vfio_pci_eventfd *eventfd; ++ ++ eventfd = rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (!eventfd) ++ return -EINVAL; ++ ++ if (count) { ++ eventfd_signal(eventfd->ctx); + return 0; + } ++ ++ return vfio_pci_eventfd_replace_locked(vdev, peventfd, NULL); + } else if (flags & VFIO_IRQ_SET_DATA_BOOL) { + uint8_t trigger; + +@@ -753,8 +759,15 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + return -EINVAL; + + trigger = *(uint8_t *)data; +- if (trigger && *ctx) +- eventfd_signal(*ctx); ++ ++ if (trigger) { ++ struct vfio_pci_eventfd *eventfd = ++ rcu_dereference_protected(*peventfd, ++ lockdep_is_held(&vdev->igate)); ++ ++ if (eventfd) ++ eventfd_signal(eventfd->ctx); ++ } + + return 0; + } else if (flags & VFIO_IRQ_SET_DATA_EVENTFD) { +@@ -765,22 +778,23 @@ static int vfio_pci_set_ctx_trigger_single(struct eventfd_ctx **ctx, + + fd = *(int32_t *)data; + if (fd == -1) { +- if (*ctx) +- eventfd_ctx_put(*ctx); +- *ctx = NULL; ++ return vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, NULL); + } else if (fd >= 0) { + struct eventfd_ctx *efdctx; ++ int ret; + + efdctx = eventfd_ctx_fdget(fd); + if (IS_ERR(efdctx)) + return PTR_ERR(efdctx); + +- if (*ctx) +- eventfd_ctx_put(*ctx); ++ ret = vfio_pci_eventfd_replace_locked(vdev, ++ peventfd, efdctx); ++ if (ret) ++ eventfd_ctx_put(efdctx); + +- *ctx = efdctx; ++ return ret; + } +- return 0; + } + + return -EINVAL; +@@ -793,7 +807,7 @@ static int vfio_pci_set_err_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_ERR_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->err_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->err_trigger, + count, flags, data); + } + +@@ -804,7 +818,7 @@ static int vfio_pci_set_req_trigger(struct vfio_pci_core_device *vdev, + if (index != VFIO_PCI_REQ_IRQ_INDEX || start != 0 || count > 1) + return -EINVAL; + +- return vfio_pci_set_ctx_trigger_single(&vdev->req_trigger, ++ return vfio_pci_set_ctx_trigger_single(vdev, &vdev->req_trigger, + count, flags, data); + } + +diff --git a/drivers/vfio/pci/vfio_pci_priv.h b/drivers/vfio/pci/vfio_pci_priv.h +index a9972eacb2936..97d992c063229 100644 +--- a/drivers/vfio/pci/vfio_pci_priv.h ++++ b/drivers/vfio/pci/vfio_pci_priv.h +@@ -26,6 +26,10 @@ struct vfio_pci_ioeventfd { + bool vfio_pci_intx_mask(struct vfio_pci_core_device *vdev); + void vfio_pci_intx_unmask(struct vfio_pci_core_device *vdev); + ++int vfio_pci_eventfd_replace_locked(struct vfio_pci_core_device *vdev, ++ struct vfio_pci_eventfd __rcu **peventfd, ++ struct eventfd_ctx *ctx); ++ + int vfio_pci_set_irqs_ioctl(struct vfio_pci_core_device *vdev, uint32_t flags, + unsigned index, unsigned start, unsigned count, + void *data); +diff --git a/include/linux/vfio_pci_core.h b/include/linux/vfio_pci_core.h +index f541044e42a2a..f5c93787f8e0b 100644 +--- a/include/linux/vfio_pci_core.h ++++ b/include/linux/vfio_pci_core.h +@@ -12,6 +12,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -27,6 +28,11 @@ + struct vfio_pci_core_device; + struct vfio_pci_region; + ++struct vfio_pci_eventfd { ++ struct eventfd_ctx *ctx; ++ struct rcu_head rcu; ++}; ++ + struct vfio_pci_regops { + ssize_t (*rw)(struct vfio_pci_core_device *vdev, char __user *buf, + size_t count, loff_t *ppos, bool iswrite); +@@ -83,8 +89,8 @@ struct vfio_pci_core_device { + struct pci_saved_state *pci_saved_state; + struct pci_saved_state *pm_save; + int ioeventfds_nr; +- struct eventfd_ctx *err_trigger; +- struct eventfd_ctx *req_trigger; ++ struct vfio_pci_eventfd __rcu *err_trigger; ++ struct vfio_pci_eventfd __rcu *req_trigger; + struct eventfd_ctx *pm_wake_eventfd_ctx; + struct list_head dummy_resources_list; + struct mutex ioeventfds_lock; +-- +2.51.0 + diff --git a/queue-6.18/vhost-fix-kthread-worker-cgroup-failure-handling.patch b/queue-6.18/vhost-fix-kthread-worker-cgroup-failure-handling.patch new file mode 100644 index 0000000000..491575a9c1 --- /dev/null +++ b/queue-6.18/vhost-fix-kthread-worker-cgroup-failure-handling.patch @@ -0,0 +1,45 @@ +From a7403e9d8917be4cd597a03b516df92382d3cd20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 14:43:58 -0500 +Subject: vhost: Fix kthread worker cgroup failure handling + +From: Mike Christie + +[ Upstream commit f3f64c2eaffbc3169bbe1e5d1e897e6dacc839d1 ] + +If we fail to attach to a cgroup we are leaking the id. This adds +a new goto to free the id. + +Fixes: 7d9896e9f6d0 ("vhost: Reintroduce kthread API and add mode selection") +Signed-off-by: Mike Christie +Acked-by: Jason Wang +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251101194358.13605-1-michael.christie@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vhost/vhost.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c +index a78226b37739d..bccdc9eab267a 100644 +--- a/drivers/vhost/vhost.c ++++ b/drivers/vhost/vhost.c +@@ -804,11 +804,13 @@ static int vhost_kthread_worker_create(struct vhost_worker *worker, + + ret = vhost_attach_task_to_cgroups(worker); + if (ret) +- goto stop_worker; ++ goto free_id; + + worker->id = id; + return 0; + ++free_id: ++ xa_erase(&dev->worker_xa, id); + stop_worker: + vhost_kthread_do_stop(worker); + return ret; +-- +2.51.0 + diff --git a/queue-6.18/virtio-clean-up-features-qword-dword-terms.patch b/queue-6.18/virtio-clean-up-features-qword-dword-terms.patch new file mode 100644 index 0000000000..5d3ae411fd --- /dev/null +++ b/queue-6.18/virtio-clean-up-features-qword-dword-terms.patch @@ -0,0 +1,376 @@ +From f97d6fbd0ba6d3ea7c94549f9d910ea99a08322b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 10:56:57 -0400 +Subject: virtio: clean up features qword/dword terms + +From: Michael S. Tsirkin + +[ Upstream commit 9513f25056b22100ddffe24898c587873b0d022c ] + +virtio pci uses word to mean "16 bits". mmio uses it to mean +"32 bits". + +To avoid confusion, let's avoid the term in core virtio +altogether. Just say U64 to mean "64 bit". + +Fixes: e7d4c1c5a546 ("virtio: introduce extended features") +Cc: Paolo Abeni +Acked-by: Jason Wang +Message-ID: +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + drivers/vhost/net.c | 12 +++++------ + drivers/virtio/virtio.c | 12 +++++------ + drivers/virtio/virtio_debug.c | 10 ++++----- + drivers/virtio/virtio_pci_modern_dev.c | 6 +++--- + include/linux/virtio.h | 2 +- + include/linux/virtio_config.h | 2 +- + include/linux/virtio_features.h | 29 +++++++++++++------------- + include/linux/virtio_pci_modern.h | 8 +++---- + 8 files changed, 41 insertions(+), 40 deletions(-) + +diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c +index 8f7f50acb6d63..1e77c0482b849 100644 +--- a/drivers/vhost/net.c ++++ b/drivers/vhost/net.c +@@ -69,7 +69,7 @@ MODULE_PARM_DESC(experimental_zcopytx, "Enable Zero Copy TX;" + + #define VHOST_DMA_IS_DONE(len) ((__force u32)(len) >= (__force u32)VHOST_DMA_DONE_LEN) + +-static const u64 vhost_net_features[VIRTIO_FEATURES_DWORDS] = { ++static const u64 vhost_net_features[VIRTIO_FEATURES_U64S] = { + VHOST_FEATURES | + (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) | + (1ULL << VIRTIO_NET_F_MRG_RXBUF) | +@@ -1731,7 +1731,7 @@ static long vhost_net_set_owner(struct vhost_net *n) + static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + unsigned long arg) + { +- u64 all_features[VIRTIO_FEATURES_DWORDS]; ++ u64 all_features[VIRTIO_FEATURES_U64S]; + struct vhost_net *n = f->private_data; + void __user *argp = (void __user *)arg; + u64 __user *featurep = argp; +@@ -1763,7 +1763,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + + /* Copy the net features, up to the user-provided buffer size */ + argp += sizeof(u64); +- copied = min(count, VIRTIO_FEATURES_DWORDS); ++ copied = min(count, (u64)VIRTIO_FEATURES_U64S); + if (copy_to_user(argp, vhost_net_features, + copied * sizeof(u64))) + return -EFAULT; +@@ -1778,13 +1778,13 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + + virtio_features_zero(all_features); + argp += sizeof(u64); +- copied = min(count, VIRTIO_FEATURES_DWORDS); ++ copied = min(count, (u64)VIRTIO_FEATURES_U64S); + if (copy_from_user(all_features, argp, copied * sizeof(u64))) + return -EFAULT; + + /* + * Any feature specified by user-space above +- * VIRTIO_FEATURES_MAX is not supported by definition. ++ * VIRTIO_FEATURES_BITS is not supported by definition. + */ + for (i = copied; i < count; ++i) { + if (copy_from_user(&features, featurep + 1 + i, +@@ -1794,7 +1794,7 @@ static long vhost_net_ioctl(struct file *f, unsigned int ioctl, + return -EOPNOTSUPP; + } + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; i++) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; i++) + if (all_features[i] & ~vhost_net_features[i]) + return -EOPNOTSUPP; + +diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c +index a09eb4d62f82d..5bdc6b82b30b4 100644 +--- a/drivers/virtio/virtio.c ++++ b/drivers/virtio/virtio.c +@@ -53,7 +53,7 @@ static ssize_t features_show(struct device *_d, + + /* We actually represent this as a bitstring, as it could be + * arbitrary length in future. */ +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) + len += sysfs_emit_at(buf, len, "%c", + __virtio_test_bit(dev, i) ? '1' : '0'); + len += sysfs_emit_at(buf, len, "\n"); +@@ -272,8 +272,8 @@ static int virtio_dev_probe(struct device *_d) + int err, i; + struct virtio_device *dev = dev_to_virtio(_d); + struct virtio_driver *drv = drv_to_virtio(dev->dev.driver); +- u64 device_features[VIRTIO_FEATURES_DWORDS]; +- u64 driver_features[VIRTIO_FEATURES_DWORDS]; ++ u64 device_features[VIRTIO_FEATURES_U64S]; ++ u64 driver_features[VIRTIO_FEATURES_U64S]; + u64 driver_features_legacy; + + /* We have a driver! */ +@@ -286,7 +286,7 @@ static int virtio_dev_probe(struct device *_d) + virtio_features_zero(driver_features); + for (i = 0; i < drv->feature_table_size; i++) { + unsigned int f = drv->feature_table[i]; +- if (!WARN_ON_ONCE(f >= VIRTIO_FEATURES_MAX)) ++ if (!WARN_ON_ONCE(f >= VIRTIO_FEATURES_BITS)) + virtio_features_set_bit(driver_features, f); + } + +@@ -303,7 +303,7 @@ static int virtio_dev_probe(struct device *_d) + } + + if (virtio_features_test_bit(device_features, VIRTIO_F_VERSION_1)) { +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; ++i) + dev->features_array[i] = driver_features[i] & + device_features[i]; + } else { +@@ -325,7 +325,7 @@ static int virtio_dev_probe(struct device *_d) + goto err; + + if (drv->validate) { +- u64 features[VIRTIO_FEATURES_DWORDS]; ++ u64 features[VIRTIO_FEATURES_U64S]; + + virtio_features_copy(features, dev->features_array); + err = drv->validate(dev); +diff --git a/drivers/virtio/virtio_debug.c b/drivers/virtio/virtio_debug.c +index d58713ddf2e58..ccf1955a1183a 100644 +--- a/drivers/virtio/virtio_debug.c ++++ b/drivers/virtio/virtio_debug.c +@@ -8,12 +8,12 @@ static struct dentry *virtio_debugfs_dir; + + static int virtio_debug_device_features_show(struct seq_file *s, void *data) + { +- u64 device_features[VIRTIO_FEATURES_DWORDS]; ++ u64 device_features[VIRTIO_FEATURES_U64S]; + struct virtio_device *dev = s->private; + unsigned int i; + + virtio_get_features(dev, device_features); +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { + if (virtio_features_test_bit(device_features, i)) + seq_printf(s, "%u\n", i); + } +@@ -26,7 +26,7 @@ static int virtio_debug_filter_features_show(struct seq_file *s, void *data) + struct virtio_device *dev = s->private; + unsigned int i; + +- for (i = 0; i < VIRTIO_FEATURES_MAX; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS; i++) { + if (virtio_features_test_bit(dev->debugfs_filter_features, i)) + seq_printf(s, "%u\n", i); + } +@@ -50,7 +50,7 @@ static int virtio_debug_filter_feature_add(void *data, u64 val) + { + struct virtio_device *dev = data; + +- if (val >= VIRTIO_FEATURES_MAX) ++ if (val >= VIRTIO_FEATURES_BITS) + return -EINVAL; + + virtio_features_set_bit(dev->debugfs_filter_features, val); +@@ -64,7 +64,7 @@ static int virtio_debug_filter_feature_del(void *data, u64 val) + { + struct virtio_device *dev = data; + +- if (val >= VIRTIO_FEATURES_MAX) ++ if (val >= VIRTIO_FEATURES_BITS) + return -EINVAL; + + virtio_features_clear_bit(dev->debugfs_filter_features, val); +diff --git a/drivers/virtio/virtio_pci_modern_dev.c b/drivers/virtio/virtio_pci_modern_dev.c +index 9e503b7a58d81..413a8c3534638 100644 +--- a/drivers/virtio/virtio_pci_modern_dev.c ++++ b/drivers/virtio/virtio_pci_modern_dev.c +@@ -401,7 +401,7 @@ void vp_modern_get_extended_features(struct virtio_pci_modern_device *mdev, + int i; + + virtio_features_zero(features); +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u64 cur; + + vp_iowrite32(i, &cfg->device_feature_select); +@@ -427,7 +427,7 @@ vp_modern_get_driver_extended_features(struct virtio_pci_modern_device *mdev, + int i; + + virtio_features_zero(features); +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u64 cur; + + vp_iowrite32(i, &cfg->guest_feature_select); +@@ -448,7 +448,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, + struct virtio_pci_common_cfg __iomem *cfg = mdev->common; + int i; + +- for (i = 0; i < VIRTIO_FEATURES_WORDS; i++) { ++ for (i = 0; i < VIRTIO_FEATURES_BITS / 32; i++) { + u32 cur = features[i >> 1] >> (32 * (i & 1)); + + vp_iowrite32(i, &cfg->guest_feature_select); +diff --git a/include/linux/virtio.h b/include/linux/virtio.h +index 96c66126c0741..132a474e59140 100644 +--- a/include/linux/virtio.h ++++ b/include/linux/virtio.h +@@ -177,7 +177,7 @@ struct virtio_device { + union virtio_map vmap; + #ifdef CONFIG_VIRTIO_DEBUG + struct dentry *debugfs_dir; +- u64 debugfs_filter_features[VIRTIO_FEATURES_DWORDS]; ++ u64 debugfs_filter_features[VIRTIO_FEATURES_U64S]; + #endif + }; + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index a1af2676bbe6a..69f84ea85d71a 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -80,7 +80,7 @@ struct virtqueue_info { + * Returns the first 64 feature bits. + * @get_extended_features: + * vdev: the virtio_device +- * Returns the first VIRTIO_FEATURES_MAX feature bits (all we currently ++ * Returns the first VIRTIO_FEATURES_BITS feature bits (all we currently + * need). + * @finalize_features: confirm what device features we'll be using. + * vdev: the virtio_device +diff --git a/include/linux/virtio_features.h b/include/linux/virtio_features.h +index f748f2f87de8d..ea2ad8717882e 100644 +--- a/include/linux/virtio_features.h ++++ b/include/linux/virtio_features.h +@@ -4,15 +4,16 @@ + + #include + +-#define VIRTIO_FEATURES_DWORDS 2 +-#define VIRTIO_FEATURES_MAX (VIRTIO_FEATURES_DWORDS * 64) +-#define VIRTIO_FEATURES_WORDS (VIRTIO_FEATURES_DWORDS * 2) ++#define VIRTIO_FEATURES_U64S 2 ++#define VIRTIO_FEATURES_BITS (VIRTIO_FEATURES_U64S * 64) ++ + #define VIRTIO_BIT(b) BIT_ULL((b) & 0x3f) +-#define VIRTIO_DWORD(b) ((b) >> 6) ++#define VIRTIO_U64(b) ((b) >> 6) ++ + #define VIRTIO_DECLARE_FEATURES(name) \ + union { \ + u64 name; \ +- u64 name##_array[VIRTIO_FEATURES_DWORDS];\ ++ u64 name##_array[VIRTIO_FEATURES_U64S];\ + } + + static inline bool virtio_features_chk_bit(unsigned int bit) +@@ -22,9 +23,9 @@ static inline bool virtio_features_chk_bit(unsigned int bit) + * Don't care returning the correct value: the build + * will fail before any bad features access + */ +- BUILD_BUG_ON(bit >= VIRTIO_FEATURES_MAX); ++ BUILD_BUG_ON(bit >= VIRTIO_FEATURES_BITS); + } else { +- if (WARN_ON_ONCE(bit >= VIRTIO_FEATURES_MAX)) ++ if (WARN_ON_ONCE(bit >= VIRTIO_FEATURES_BITS)) + return false; + } + return true; +@@ -34,26 +35,26 @@ static inline bool virtio_features_test_bit(const u64 *features, + unsigned int bit) + { + return virtio_features_chk_bit(bit) && +- !!(features[VIRTIO_DWORD(bit)] & VIRTIO_BIT(bit)); ++ !!(features[VIRTIO_U64(bit)] & VIRTIO_BIT(bit)); + } + + static inline void virtio_features_set_bit(u64 *features, + unsigned int bit) + { + if (virtio_features_chk_bit(bit)) +- features[VIRTIO_DWORD(bit)] |= VIRTIO_BIT(bit); ++ features[VIRTIO_U64(bit)] |= VIRTIO_BIT(bit); + } + + static inline void virtio_features_clear_bit(u64 *features, + unsigned int bit) + { + if (virtio_features_chk_bit(bit)) +- features[VIRTIO_DWORD(bit)] &= ~VIRTIO_BIT(bit); ++ features[VIRTIO_U64(bit)] &= ~VIRTIO_BIT(bit); + } + + static inline void virtio_features_zero(u64 *features) + { +- memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_DWORDS); ++ memset(features, 0, sizeof(features[0]) * VIRTIO_FEATURES_U64S); + } + + static inline void virtio_features_from_u64(u64 *features, u64 from) +@@ -66,7 +67,7 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) + { + int i; + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; ++i) + if (f1[i] != f2[i]) + return false; + return true; +@@ -74,14 +75,14 @@ static inline bool virtio_features_equal(const u64 *f1, const u64 *f2) + + static inline void virtio_features_copy(u64 *to, const u64 *from) + { +- memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_DWORDS); ++ memcpy(to, from, sizeof(to[0]) * VIRTIO_FEATURES_U64S); + } + + static inline void virtio_features_andnot(u64 *to, const u64 *f1, const u64 *f2) + { + int i; + +- for (i = 0; i < VIRTIO_FEATURES_DWORDS; i++) ++ for (i = 0; i < VIRTIO_FEATURES_U64S; i++) + to[i] = f1[i] & ~f2[i]; + } + +diff --git a/include/linux/virtio_pci_modern.h b/include/linux/virtio_pci_modern.h +index 48bc12d1045bd..9a3f2fc53bd65 100644 +--- a/include/linux/virtio_pci_modern.h ++++ b/include/linux/virtio_pci_modern.h +@@ -107,7 +107,7 @@ void vp_modern_set_extended_features(struct virtio_pci_modern_device *mdev, + static inline u64 + vp_modern_get_features(struct virtio_pci_modern_device *mdev) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + + vp_modern_get_extended_features(mdev, features_array); + return features_array[0]; +@@ -116,11 +116,11 @@ vp_modern_get_features(struct virtio_pci_modern_device *mdev) + static inline u64 + vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + int i; + + vp_modern_get_driver_extended_features(mdev, features_array); +- for (i = 1; i < VIRTIO_FEATURES_DWORDS; ++i) ++ for (i = 1; i < VIRTIO_FEATURES_U64S; ++i) + WARN_ON_ONCE(features_array[i]); + return features_array[0]; + } +@@ -128,7 +128,7 @@ vp_modern_get_driver_features(struct virtio_pci_modern_device *mdev) + static inline void + vp_modern_set_features(struct virtio_pci_modern_device *mdev, u64 features) + { +- u64 features_array[VIRTIO_FEATURES_DWORDS]; ++ u64 features_array[VIRTIO_FEATURES_U64S]; + + virtio_features_from_u64(features_array, features); + vp_modern_set_extended_features(mdev, features_array); +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-grammar-in-virtio_map_ops-docs.patch b/queue-6.18/virtio-fix-grammar-in-virtio_map_ops-docs.patch new file mode 100644 index 0000000000..c5a85beb15 --- /dev/null +++ b/queue-6.18/virtio-fix-grammar-in-virtio_map_ops-docs.patch @@ -0,0 +1,40 @@ +From fde7ccdd7a3875f2e5bf82439956bd047d77781b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:38 -0500 +Subject: virtio: fix grammar in virtio_map_ops docs + +From: Michael S. Tsirkin + +[ Upstream commit c15f42e09178d2849744ccf064200f5e7f71e688 ] + +Fix grammar issues in the virtio_map_ops docs: +- missing article before "transport" +- "implements" -> "implement" to match subject + +Fixes: bee8c7c24b73 ("virtio: introduce map ops in virtio core") +Message-Id: <3f7bcae5a984f14b72e67e82572b110acb06fa7e.1763026134.git.mst@redhat.com> +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 78cf4119f5674..6660132258d40 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -141,8 +141,8 @@ struct virtio_config_ops { + + /** + * struct virtio_map_ops - operations for mapping buffer for a virtio device +- * Note: For transport that has its own mapping logic it must +- * implements all of the operations ++ * Note: For a transport that has its own mapping logic it must ++ * implement all of the operations + * @map_page: map a buffer to the device + * map: metadata for performing mapping + * page: the page that will be mapped by the device +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-grammar-in-virtio_queue_info-docs.patch b/queue-6.18/virtio-fix-grammar-in-virtio_queue_info-docs.patch new file mode 100644 index 0000000000..f43202b2c2 --- /dev/null +++ b/queue-6.18/virtio-fix-grammar-in-virtio_queue_info-docs.patch @@ -0,0 +1,36 @@ +From be6bcf658f27aca3b6f3a9fb3ad5f0656c951933 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:36 -0500 +Subject: virtio: fix grammar in virtio_queue_info docs + +From: Michael S. Tsirkin + +[ Upstream commit 63598fba55ab9d384818fed48dc04006cecf7be4 ] + +Fix grammar in the description of @ctx + +Fixes: c502eb85c34e ("virtio: introduce virtio_queue_info struct and find_vqs_info() config op") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index dbc7eff1f101f..78cf4119f5674 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -24,7 +24,7 @@ typedef void vq_callback_t(struct virtqueue *); + * a virtqueue unused by the driver. + * @callback: A callback to invoke on a used buffer notification. + * NULL for a virtqueue that does not need a callback. +- * @ctx: A flag to indicate to maintain an extra context per virtqueue. ++ * @ctx: whether to maintain an extra context per virtqueue. + */ + struct virtqueue_info { + const char *name; +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-kernel-doc-for-mapping-free_coherent-func.patch b/queue-6.18/virtio-fix-kernel-doc-for-mapping-free_coherent-func.patch new file mode 100644 index 0000000000..78d8c9788d --- /dev/null +++ b/queue-6.18/virtio-fix-kernel-doc-for-mapping-free_coherent-func.patch @@ -0,0 +1,75 @@ +From 8dafa1f76e131a4f7c6a11538b2f6ab0ab026678 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:29:20 +0000 +Subject: virtio: fix kernel-doc for mapping/free_coherent functions + +From: Kriish Sharma + +[ Upstream commit f8113000855a8cc2c6d8e19b97a390f1c082285d ] + +Documentation build reported: + + WARNING: ./drivers/virtio/virtio_ring.c:3174 function parameter 'vaddr' not described in 'virtqueue_map_free_coherent' + WARNING: ./drivers/virtio/virtio_ring.c:3308 expecting prototype for virtqueue_mapping_error(). Prototype was for virtqueue_map_mapping_error() instead + +The kernel-doc block for virtqueue_map_free_coherent() omitted the @vaddr parameter, and +the kernel-doc header for virtqueue_map_mapping_error() used the wrong function name +(virtqueue_mapping_error) instead of the actual function name. + +This change updates: + + - the function name in the comment to virtqueue_map_mapping_error() + - adds the missing @vaddr description in the comment for virtqueue_map_free_coherent() + +Fixes: b41cb3bcf67f ("virtio: rename dma helpers") +Signed-off-by: Kriish Sharma +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251110202920.2250244-1-kriish.sharma2006@gmail.com> +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_ring.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c +index 7b6205253b46b..ddab689596717 100644 +--- a/drivers/virtio/virtio_ring.c ++++ b/drivers/virtio/virtio_ring.c +@@ -3166,6 +3166,7 @@ EXPORT_SYMBOL_GPL(virtqueue_map_alloc_coherent); + * @vdev: the virtio device we are talking to + * @map: metadata for performing mapping + * @size: the size of the buffer ++ * @vaddr: the virtual address that needs to be freed + * @map_handle: the mapped address that needs to be freed + * + */ +@@ -3190,7 +3191,7 @@ EXPORT_SYMBOL_GPL(virtqueue_map_free_coherent); + * @dir: mapping direction + * @attrs: mapping attributes + * +- * Returns mapped address. Caller should check that by virtqueue_mapping_error(). ++ * Returns mapped address. Caller should check that by virtqueue_map_mapping_error(). + */ + dma_addr_t virtqueue_map_page_attrs(const struct virtqueue *_vq, + struct page *page, +@@ -3249,7 +3250,7 @@ EXPORT_SYMBOL_GPL(virtqueue_unmap_page_attrs); + * The caller calls this to do dma mapping in advance. The DMA address can be + * passed to this _vq when it is in pre-mapped mode. + * +- * return mapped address. Caller should check that by virtqueue_mapping_error(). ++ * return mapped address. Caller should check that by virtqueue_map_mapping_error(). + */ + dma_addr_t virtqueue_map_single_attrs(const struct virtqueue *_vq, void *ptr, + size_t size, +@@ -3299,7 +3300,7 @@ void virtqueue_unmap_single_attrs(const struct virtqueue *_vq, + EXPORT_SYMBOL_GPL(virtqueue_unmap_single_attrs); + + /** +- * virtqueue_mapping_error - check dma address ++ * virtqueue_map_mapping_error - check dma address + * @_vq: the struct virtqueue we're talking about. + * @addr: DMA address + * +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-map-ops-comment.patch b/queue-6.18/virtio-fix-map-ops-comment.patch new file mode 100644 index 0000000000..2bdea88d68 --- /dev/null +++ b/queue-6.18/virtio-fix-map-ops-comment.patch @@ -0,0 +1,36 @@ +From e4898b4c7ea2eade883a877a982130fe1952765c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:49 -0500 +Subject: virtio: fix map ops comment + +From: Michael S. Tsirkin + +[ Upstream commit deb55fc994e3dc38f139c0147c15fc2a9db27086 ] + +@free will free the map handle not sync it. Fix the doc to match. + +Fixes: bee8c7c24b73 ("virtio: introduce map ops in virtio core") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 1a019a1f168d5..a1af2676bbe6a 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -177,7 +177,7 @@ struct virtio_config_ops { + * map: metadata for performing mapping + * size: the size of the buffer + * vaddr: virtual address of the buffer +- * map_handle: the mapping address to sync ++ * map_handle: the mapping address that needs to be freed + * attrs: unmapping attributes + * @need_sync: if the buffer needs synchronization + * map: metadata for performing mapping +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-typo-in-virtio_device_ready-comment.patch b/queue-6.18/virtio-fix-typo-in-virtio_device_ready-comment.patch new file mode 100644 index 0000000000..723360eb33 --- /dev/null +++ b/queue-6.18/virtio-fix-typo-in-virtio_device_ready-comment.patch @@ -0,0 +1,36 @@ +From df6a7bbe329c9b615bc27a7508095cb244c65580 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:31 -0500 +Subject: virtio: fix typo in virtio_device_ready() comment + +From: Michael S. Tsirkin + +[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ] + +"coherenct" -> "coherent" + +Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 16001e9f9b391..1ea5baa62141f 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -362,7 +362,7 @@ void virtio_device_ready(struct virtio_device *dev) + * specific set_status() method. + * + * A well behaved device will only notify a virtqueue after +- * DRIVER_OK, this means the device should "see" the coherenct ++ * DRIVER_OK, this means the device should "see" the coherent + * memory write that set vq->broken as false which is done by + * the driver when it sees DRIVER_OK, then the following + * driver's vring_interrupt() will see vq->broken as false so +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-6.18/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..9dacdbeff0 --- /dev/null +++ b/queue-6.18/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From 7c93a74420aee7ca8e79d4fc2a37e6a799f19630 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index e231147ff92db..1a019a1f168d5 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -384,7 +384,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu_mask: the cpu mask + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-6.18/virtio-fix-whitespace-in-virtio_config_ops.patch b/queue-6.18/virtio-fix-whitespace-in-virtio_config_ops.patch new file mode 100644 index 0000000000..6cc3275ffe --- /dev/null +++ b/queue-6.18/virtio-fix-whitespace-in-virtio_config_ops.patch @@ -0,0 +1,37 @@ +From dd8bdd8ed2dae6b0803103ee889ec6d6acaec1a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:34 -0500 +Subject: virtio: fix whitespace in virtio_config_ops + +From: Michael S. Tsirkin + +[ Upstream commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 ] + +The finalize_features documentation uses a tab between words. +Use space instead. + +Fixes: d16c0cd27331 ("docs: driver-api: virtio: virtio on Linux") +Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com> +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 1ea5baa62141f..dbc7eff1f101f 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -86,7 +86,7 @@ struct virtqueue_info { + * vdev: the virtio_device + * This sends the driver feature bits to the device: it can change + * the dev->feature bits if it wants. +- * Note that despite the name this can be called any number of ++ * Note that despite the name this can be called any number of + * times. + * Returns 0 on success or error status + * @bus_name: return the bus name associated with the device (optional) +-- +2.51.0 + diff --git a/queue-6.18/virtio-standardize-returns-documentation-style.patch b/queue-6.18/virtio-standardize-returns-documentation-style.patch new file mode 100644 index 0000000000..9413a79bc6 --- /dev/null +++ b/queue-6.18/virtio-standardize-returns-documentation-style.patch @@ -0,0 +1,65 @@ +From 18adebeaadf9c12ecf909b7da37420408ee9fd52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:41 -0500 +Subject: virtio: standardize Returns documentation style + +From: Michael S. Tsirkin + +[ Upstream commit 5e88a5a97d113619b674ebfdd1d2065f2edd10eb ] + +Remove colons after "Returns" in virtio_map_ops function +documentation - both to avoid triggering an htmldoc warning +and for consistency with virtio_config_ops. + +This affects map_page, alloc, need_sync, and max_mapping_size. + +Fixes: bee8c7c24b73 ("virtio: introduce map ops in virtio core") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 6660132258d40..e231147ff92db 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -150,7 +150,7 @@ struct virtio_config_ops { + * size: the buffer size + * dir: mapping direction + * attrs: mapping attributes +- * Returns: the mapped address ++ * Returns the mapped address + * @unmap_page: unmap a buffer from the device + * map: device specific mapping map + * map_handle: the mapped address +@@ -172,7 +172,7 @@ struct virtio_config_ops { + * size: the size of the buffer + * map_handle: the mapping address to sync + * gfp: allocation flag (GFP_XXX) +- * Returns: virtual address of the allocated buffer ++ * Returns virtual address of the allocated buffer + * @free: free a coherent buffer mapping + * map: metadata for performing mapping + * size: the size of the buffer +@@ -182,13 +182,13 @@ struct virtio_config_ops { + * @need_sync: if the buffer needs synchronization + * map: metadata for performing mapping + * map_handle: the mapped address +- * Returns: whether the buffer needs synchronization ++ * Returns whether the buffer needs synchronization + * @mapping_error: if the mapping address is error + * map: metadata for performing mapping + * map_handle: the mapped address + * @max_mapping_size: get the maximum buffer size that can be mapped + * map: metadata for performing mapping +- * Returns: the maximum buffer size that can be mapped ++ * Returns the maximum buffer size that can be mapped + */ + struct virtio_map_ops { + dma_addr_t (*map_page)(union virtio_map map, struct page *page, +-- +2.51.0 + diff --git a/queue-6.18/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-6.18/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..8117aab0f1 --- /dev/null +++ b/queue-6.18/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From 9001b316ba97f806b9eeb2ec2d11f41e671f0853 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index f9a29045eca0d..0a801f67b5996 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -80,7 +80,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-6.18/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch b/queue-6.18/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch new file mode 100644 index 0000000000..196a7b4a0d --- /dev/null +++ b/queue-6.18/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch @@ -0,0 +1,51 @@ +From b5b18518b5f1abf53a3c3c21d54ba2738695ff53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 16:42:20 +0800 +Subject: watchdog: starfive: Fix resource leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 5bcc5786a0cfa9249ccbe539833040a6285d0de3 ] + +If pm_runtime_put_sync() fails after watchdog_register_device() +succeeds, the probe function jumps to err_exit without +unregistering the watchdog device. This leaves the watchdog +registered in the subsystem while the driver fails to load, +resulting in a resource leak. + +Add a new error label err_unregister_wdt to properly unregister +the watchdog device. + +Fixes: 8bc22a2f1bf0 ("watchdog: starfive: Check pm_runtime_enabled() before decrementing usage counter") +Signed-off-by: Haotian Zhang +Reviewed-by: Wim Van Sebroeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/starfive-wdt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c +index 355918d62f63d..ed71d3960a0f2 100644 +--- a/drivers/watchdog/starfive-wdt.c ++++ b/drivers/watchdog/starfive-wdt.c +@@ -500,12 +500,14 @@ static int starfive_wdt_probe(struct platform_device *pdev) + if (pm_runtime_enabled(&pdev->dev)) { + ret = pm_runtime_put_sync(&pdev->dev); + if (ret) +- goto err_exit; ++ goto err_unregister_wdt; + } + } + + return 0; + ++err_unregister_wdt: ++ watchdog_unregister_device(&wdt->wdd); + err_exit: + starfive_wdt_disable_clock(wdt); + pm_runtime_disable(&pdev->dev); +-- +2.51.0 + diff --git a/queue-6.18/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-6.18/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..3b2b2323bd --- /dev/null +++ b/queue-6.18/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From b5e15f68ec0727292fb0a4be5594922d7352ea80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 650fdc7996e1c..dd3c2d69c9df1 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -326,19 +326,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); +@@ -355,15 +363,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -385,8 +398,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -417,7 +432,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -425,8 +441,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -443,7 +461,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -460,12 +478,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + static int wdat_wdt_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch b/queue-6.18/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch new file mode 100644 index 0000000000..ac833d23cc --- /dev/null +++ b/queue-6.18/wifi-ath10k-move-recovery-check-logic-into-a-new-wor.patch @@ -0,0 +1,158 @@ +From 88ebc6b83b9f37be9f3b83f197f2a70bc7d196bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 19:07:57 +0800 +Subject: wifi: ath10k: move recovery check logic into a new work +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kang Yang + +[ Upstream commit f35a07a4842a88801d9182b1a76d178bfa616978 ] + +Currently, ath10k has a recovery check logic. It will wait for the +last recovery to finish by wait_for_completion_timeout(); + +But in SDIO scenarios, the recovery function may be invoked from +interrupt context, where long blocking waits are undesirable and can +lead to system instability. + +Additionally, Linux’s ordered workqueue processes one task at a time. +If a previous recovery is still queued or executing, new triggers are +ignored. This prevents accurate tracking of consecutive failures and +delays transition to the WEDGED state. + +To address this, move the recovery check logic into a different +workqueue. + +Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00288-QCARMSWPZ-1 +Tested-on: QCA6174 hw3.2 SDIO WLAN.RMH.4.4.1-00189 + +Fixes: c256a94d1b1b ("wifi: ath10k: shutdown driver when hardware is unreliable") +Signed-off-by: Kang Yang +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251014110757.155-1-kang.yang@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath10k/core.c | 20 +++++++++----------- + drivers/net/wireless/ath/ath10k/core.h | 2 +- + drivers/net/wireless/ath/ath10k/mac.c | 2 +- + 3 files changed, 11 insertions(+), 13 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c +index 6f78f1752cd6f..9ae3595fb6986 100644 +--- a/drivers/net/wireless/ath/ath10k/core.c ++++ b/drivers/net/wireless/ath/ath10k/core.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -2493,8 +2492,9 @@ static int ath10k_init_hw_params(struct ath10k *ar) + return 0; + } + +-static bool ath10k_core_needs_recovery(struct ath10k *ar) ++static void ath10k_core_recovery_check_work(struct work_struct *work) + { ++ struct ath10k *ar = container_of(work, struct ath10k, recovery_check_work); + long time_left; + + /* Sometimes the recovery will fail and then the next all recovery fail, +@@ -2504,7 +2504,7 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ath10k_err(ar, "consecutive fail %d times, will shutdown driver!", + atomic_read(&ar->fail_cont_count)); + ar->state = ATH10K_STATE_WEDGED; +- return false; ++ return; + } + + ath10k_dbg(ar, ATH10K_DBG_BOOT, "total recovery count: %d", ++ar->recovery_count); +@@ -2518,27 +2518,24 @@ static bool ath10k_core_needs_recovery(struct ath10k *ar) + ATH10K_RECOVERY_TIMEOUT_HZ); + if (time_left) { + ath10k_warn(ar, "previous recovery succeeded, skip this!\n"); +- return false; ++ return; + } + + /* Record the continuous recovery fail count when recovery failed. */ + atomic_inc(&ar->fail_cont_count); + + /* Avoid having multiple recoveries at the same time. */ +- return false; ++ return; + } + + atomic_inc(&ar->pending_recovery); +- +- return true; ++ queue_work(ar->workqueue, &ar->restart_work); + } + + void ath10k_core_start_recovery(struct ath10k *ar) + { +- if (!ath10k_core_needs_recovery(ar)) +- return; +- +- queue_work(ar->workqueue, &ar->restart_work); ++ /* Use workqueue_aux to avoid blocking recovery tracking */ ++ queue_work(ar->workqueue_aux, &ar->recovery_check_work); + } + EXPORT_SYMBOL(ath10k_core_start_recovery); + +@@ -3734,6 +3731,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, + + INIT_WORK(&ar->register_work, ath10k_core_register_work); + INIT_WORK(&ar->restart_work, ath10k_core_restart); ++ INIT_WORK(&ar->recovery_check_work, ath10k_core_recovery_check_work); + INIT_WORK(&ar->set_coverage_class_work, + ath10k_core_set_coverage_class_work); + +diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h +index 8c72ed386edb7..859176fcb5a29 100644 +--- a/drivers/net/wireless/ath/ath10k/core.h ++++ b/drivers/net/wireless/ath/ath10k/core.h +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -1208,6 +1207,7 @@ struct ath10k { + + struct work_struct register_work; + struct work_struct restart_work; ++ struct work_struct recovery_check_work; + struct work_struct bundle_tx_work; + struct work_struct tx_complete_work; + +diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c +index 154ac7a709824..da6f7957a0ae7 100644 +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -3,7 +3,6 @@ + * Copyright (c) 2005-2011 Atheros Communications Inc. + * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. + * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2024 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -5428,6 +5427,7 @@ static void ath10k_stop(struct ieee80211_hw *hw, bool suspend) + cancel_work_sync(&ar->set_coverage_class_work); + cancel_delayed_work_sync(&ar->scan.timeout); + cancel_work_sync(&ar->restart_work); ++ cancel_work_sync(&ar->recovery_check_work); + } + + static int ath10k_config_ps(struct ath10k *ar) +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath11k-fix-peer-he-mcs-assignment.patch b/queue-6.18/wifi-ath11k-fix-peer-he-mcs-assignment.patch new file mode 100644 index 0000000000..bed5e3c5ca --- /dev/null +++ b/queue-6.18/wifi-ath11k-fix-peer-he-mcs-assignment.patch @@ -0,0 +1,94 @@ +From 57de378a3a1d3308073bf6ffeef5485cd19c7979 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:49:00 +0800 +Subject: wifi: ath11k: fix peer HE MCS assignment + +From: Baochen Qiang + +[ Upstream commit 4a013ca2d490c73c40588d62712ffaa432046a04 ] + +In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to +firmware as receive MCS while peer's receive MCS sent as transmit MCS, +which goes against firmwire's definition. + +While connecting to a misbehaved AP that advertises 0xffff (meaning not +supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff +is assigned to he_mcs->rx_mcs_set field. + + Ext Tag: HE Capabilities + [...] + Supported HE-MCS and NSS Set + [...] + Rx and Tx MCS Maps 160 MHz + [...] + Tx HE-MCS Map 160 MHz: 0xffff + +Swap the assignment to fix this issue. + +As the HE rate control mask is meant to limit our own transmit MCS, it +needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive MCS. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 49c639d73d58d..f142c17aa9aa7 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2522,10 +2522,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2535,10 +2535,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 649839d243293..110035dae8a61 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -2091,8 +2091,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ /* firmware interprets mcs->rx_mcs_set field as peer's ++ * RX capability ++ */ ++ he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath11k-fix-vht-mcs-assignment.patch b/queue-6.18/wifi-ath11k-fix-vht-mcs-assignment.patch new file mode 100644 index 0000000000..520b8a8e3c --- /dev/null +++ b/queue-6.18/wifi-ath11k-fix-vht-mcs-assignment.patch @@ -0,0 +1,102 @@ +From 5a0930a63df2fa49dbd9d9c873939a0b27d8b148 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:48:59 +0800 +Subject: wifi: ath11k: fix VHT MCS assignment + +From: Baochen Qiang + +[ Upstream commit 47d0cd6bccb4604192633cc8d29511e85d811fc0 ] + +While associating, firmware needs to know peer's receive capability to +calculate its own VHT transmit MCS, currently host sends this information +to firmware via mcs->rx_mcs_set field, this is wrong as firmware actually +takes it from mcs->tx_mcs_set field. Till now there is no failure seen +due to this, most likely because almost all peers are advertising the +same capability for both transmit and receive. Swap the assignment to +fix it. + +Besides, rate control mask is meant to limit our own transmit MCS, hence +need to go via mcs->tx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive +capability rather than transmit capability. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-1-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 13 ++++++++----- + drivers/net/wireless/ath/ath11k/wmi.h | 2 ++ + 3 files changed, 12 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 0e41b5a91d66d..49c639d73d58d 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2235,9 +2235,9 @@ static void ath11k_peer_assoc_h_vht(struct ath11k *ar, + arg->peer_nss = min(sta->deflink.rx_nss, max_nss); + arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); + arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); ++ arg->rx_mcs_set = ath11k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); + arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); +- arg->tx_mcs_set = ath11k_peer_assoc_h_vht_limit( +- __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); ++ arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); + + /* In IPQ8074 platform, VHT mcs rate 10 and 11 is enabled by default. + * VHT mcs rate 10 and 11 is not supported in 11ac standard. +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index e3b444333deed..649839d243293 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -2061,10 +2061,13 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + cmd->peer_bw_rxnss_override |= param->peer_bw_rxnss_override; + + if (param->vht_capable) { +- mcs->rx_max_rate = param->rx_max_rate; +- mcs->rx_mcs_set = param->rx_mcs_set; +- mcs->tx_max_rate = param->tx_max_rate; +- mcs->tx_mcs_set = param->tx_mcs_set; ++ /* firmware interprets mcs->tx_mcs_set field as peer's ++ * RX capability ++ */ ++ mcs->tx_max_rate = param->rx_max_rate; ++ mcs->tx_mcs_set = param->rx_mcs_set; ++ mcs->rx_max_rate = param->tx_max_rate; ++ mcs->rx_mcs_set = param->tx_mcs_set; + } + + /* HE Rates */ +diff --git a/drivers/net/wireless/ath/ath11k/wmi.h b/drivers/net/wireless/ath/ath11k/wmi.h +index 9fcffaa2f383c..6e9354297e71d 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.h ++++ b/drivers/net/wireless/ath/ath11k/wmi.h +@@ -4133,8 +4133,10 @@ struct wmi_rate_set { + struct wmi_vht_rate_set { + u32 tlv_header; + u32 rx_max_rate; ++ /* MCS at which the peer can transmit */ + u32 rx_mcs_set; + u32 tx_max_rate; ++ /* MCS at which the peer can receive */ + u32 tx_mcs_set; + u32 tx_max_mcs_nss; + } __packed; +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath11k-restore-register-window-after-global-res.patch b/queue-6.18/wifi-ath11k-restore-register-window-after-global-res.patch new file mode 100644 index 0000000000..13df407c2c --- /dev/null +++ b/queue-6.18/wifi-ath11k-restore-register-window-after-global-res.patch @@ -0,0 +1,89 @@ +From 3f3b2537f3bcfc729df32967141af55d8408ac95 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 10:30:20 +0800 +Subject: wifi: ath11k: restore register window after global reset + +From: Baochen Qiang + +[ Upstream commit 596b911644cc19ecba0dbc9c92849fb59390e29a ] + +Hardware target implements an address space larger than that PCI BAR can +map. In order to be able to access the whole target address space, the BAR +space is split into 4 segments, of which the last 3, called windows, can +be dynamically mapped to the desired area. This is achieved by updating +window register with appropriate window value. Currently each time when +accessing a register that beyond ATH11K_PCI_WINDOW_START, host calculates +the window value and caches it after window update, this way next time +when accessing a register falling in the same window, host knows that the +window is already good hence no additional update needed. + +However this mechanism breaks after global reset is triggered in +ath11k_pci_soc_global_reset(), because with global reset hardware resets +window register hence the window is not properly mapped any more. Current +host does nothing about this, as a result a subsequent register access may +not work as expected if it falls in a window same as before. + +Although there is no obvious issue seen now, better to fix it to avoid +future problem. The fix is done by restoring the window register after +global reset. + +Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30 + +Fixes: d5c65159f289 ("ath11k: driver for Qualcomm IEEE 802.11ax devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251014-ath11k-reset-window-cache-v1-1-b85271b111dd@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c +index d8655badd96d0..7114eca8810db 100644 +--- a/drivers/net/wireless/ath/ath11k/pci.c ++++ b/drivers/net/wireless/ath/ath11k/pci.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -177,6 +177,19 @@ static inline void ath11k_pci_select_static_window(struct ath11k_pci *ab_pci) + ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); + } + ++static void ath11k_pci_restore_window(struct ath11k_base *ab) ++{ ++ struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); ++ ++ spin_lock_bh(&ab_pci->window_lock); ++ ++ iowrite32(ATH11K_PCI_WINDOW_ENABLE_BIT | ab_pci->register_window, ++ ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); ++ ++ spin_unlock_bh(&ab_pci->window_lock); ++} ++ + static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + { + u32 val, delay; +@@ -201,6 +214,11 @@ static void ath11k_pci_soc_global_reset(struct ath11k_base *ab) + val = ath11k_pcic_read32(ab, PCIE_SOC_GLOBAL_RESET); + if (val == 0xffffffff) + ath11k_warn(ab, "link down error during global reset\n"); ++ ++ /* Restore window register as its content is cleared during ++ * hardware global reset, such that it aligns with host cache. ++ */ ++ ath11k_pci_restore_window(ab); + } + + static void ath11k_pci_clear_dbg_registers(struct ath11k_base *ab) +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-enforce-vdev-limit-in-ath12k_mac_vdev_cr.patch b/queue-6.18/wifi-ath12k-enforce-vdev-limit-in-ath12k_mac_vdev_cr.patch new file mode 100644 index 0000000000..58935b8b19 --- /dev/null +++ b/queue-6.18/wifi-ath12k-enforce-vdev-limit-in-ath12k_mac_vdev_cr.patch @@ -0,0 +1,68 @@ +From caf361b1c14186a383515d5e0d8951871886b8c0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Oct 2025 23:52:53 +0530 +Subject: wifi: ath12k: enforce vdev limit in ath12k_mac_vdev_create() + +From: Rameshkumar Sundaram + +[ Upstream commit 448bf7b51426bcca54b5ac1ddd1045a36c9d1dea ] + +Currently, vdev limit check is performed only in +ath12k_mac_assign_vif_to_vdev(). If the host has already created +maximum number of vdevs for the radio (ar) and a scan request +arrives for the same radio, ath12k_mac_initiate_hw_scan() attempts +to create a vdev without checking the limit, causing firmware asserts. + +Centralize the vdev limit guard by moving the check into +ath12k_mac_vdev_create() so that all callers obey the limit. +While doing this, update the condition from +`num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)` to +`num_created_vdevs >= TARGET_NUM_VDEVS(ab)` for clarity and to +eliminate unnecessary arithmetic. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 0d6e6736ed9f ("wifi: ath12k: scan statemachine changes for single wiphy") +Fixes: 4938ba733ee2 ("wifi: ath12k: modify remain on channel for single wiphy") +Signed-off-by: Rameshkumar Sundaram +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251026182254.1399650-2-rameshkumar.sundaram@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 0cec6c47fca29..8f139505019c4 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -9687,6 +9687,12 @@ int ath12k_mac_vdev_create(struct ath12k *ar, struct ath12k_link_vif *arvif) + if (vif->type == NL80211_IFTYPE_MONITOR && ar->monitor_vdev_created) + return -EINVAL; + ++ if (ar->num_created_vdevs >= TARGET_NUM_VDEVS(ab)) { ++ ath12k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", ++ TARGET_NUM_VDEVS(ab)); ++ return -ENOSPC; ++ } ++ + link_id = arvif->link_id; + + if (link_id < IEEE80211_MLD_MAX_NUM_LINKS) { +@@ -10046,12 +10052,6 @@ static struct ath12k *ath12k_mac_assign_vif_to_vdev(struct ieee80211_hw *hw, + if (arvif->is_created) + goto flush; + +- if (ar->num_created_vdevs > (TARGET_NUM_VDEVS(ab) - 1)) { +- ath12k_warn(ab, "failed to create vdev, reached max vdev limit %d\n", +- TARGET_NUM_VDEVS(ab)); +- goto unlock; +- } +- + ret = ath12k_mac_vdev_create(ar, arvif); + if (ret) { + ath12k_warn(ab, "failed to create vdev %pM ret %d", vif->addr, ret); +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch b/queue-6.18/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch new file mode 100644 index 0000000000..855a49520d --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-error-handling-in-creating-hardware-.patch @@ -0,0 +1,115 @@ +From c6f5ad8f8245caa4ec6c3f5ed0b6bf11b4ba2d18 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:08:43 +0800 +Subject: wifi: ath12k: fix error handling in creating hardware group + +From: Baochen Qiang + +[ Upstream commit 088a099690e4c0d291db505013317ab5dd58b4d5 ] + +In ath12k_core_init() when ath12k_core_hw_group_create() fails, +ath12k_core_hw_group_destroy() is called where for each device below +path would get executed + + ath12k_core_soc_destroy() + ath12k_qmi_deinit_service() + qmi_handle_release() + +This results in kernel crash in case one of the device fails at +qmi_handle_init() when creating hardware group: + +ath12k_pci 0000:10:00.0: failed to initialize qmi handle +ath12k_pci 0000:10:00.0: failed to initialize qmi :-517 +ath12k_pci 0000:10:00.0: failed to create soc core: -517 +ath12k_pci 0000:10:00.0: unable to create hw group +BUG: unable to handle page fault for address: ffffffffffffffb7 +RIP: 0010:qmi_handle_release +Call Trace: + + ath12k_qmi_deinit_service + ath12k_core_hw_group_destroy + ath12k_core_init + ath12k_pci_probe + +The detailed reason is, when qmi_handle_init() fails for a device +ab->qmi.handle is not correctly initialized. Then +ath12k_core_hw_group_create() returns failure, since error handing +is done for all device, eventually qmi_handle_release() is called for the +issue device and finally kernel crashes due to the uninitialized +ab->qmi.handle. + +Fix this by moving error handling to ath12k_core_hw_group_create(), this +way the issue device can be skipped. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284.1-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: 6f245ea0ec6c ("wifi: ath12k: introduce device group abstraction") +Link: https://lore.kernel.org/ath12k/fabc97122016d1a66a53ddedd965d134@posteo.net +Reported-by: a-development +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220518 +Tested-by: a-development +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251030-fix-hw-group-create-err-handling-v1-1-0659e4d15fb9@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/core.c | 22 +++++++++++++++++----- + 1 file changed, 17 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c +index 5d494c5cdc0da..a2137b363c2fe 100644 +--- a/drivers/net/wireless/ath/ath12k/core.c ++++ b/drivers/net/wireless/ath/ath12k/core.c +@@ -2106,14 +2106,27 @@ static int ath12k_core_hw_group_create(struct ath12k_hw_group *ag) + ret = ath12k_core_soc_create(ab); + if (ret) { + mutex_unlock(&ab->core_lock); +- ath12k_err(ab, "failed to create soc core: %d\n", ret); +- return ret; ++ ath12k_err(ab, "failed to create soc %d core: %d\n", i, ret); ++ goto destroy; + } + + mutex_unlock(&ab->core_lock); + } + + return 0; ++ ++destroy: ++ for (i--; i >= 0; i--) { ++ ab = ag->ab[i]; ++ if (!ab) ++ continue; ++ ++ mutex_lock(&ab->core_lock); ++ ath12k_core_soc_destroy(ab); ++ mutex_unlock(&ab->core_lock); ++ } ++ ++ return ret; + } + + void ath12k_core_hw_group_set_mlo_capable(struct ath12k_hw_group *ag) +@@ -2188,7 +2201,7 @@ int ath12k_core_init(struct ath12k_base *ab) + if (ret) { + mutex_unlock(&ag->mutex); + ath12k_warn(ab, "unable to create hw group\n"); +- goto err_destroy_hw_group; ++ goto err_unassign_hw_group; + } + } + +@@ -2196,8 +2209,7 @@ int ath12k_core_init(struct ath12k_base *ab) + + return 0; + +-err_destroy_hw_group: +- ath12k_core_hw_group_destroy(ab->ag); ++err_unassign_hw_group: + ath12k_core_hw_group_unassign(ab); + err_unregister_notifier: + ath12k_core_panic_notifier_unregister(ab); +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch b/queue-6.18/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch new file mode 100644 index 0000000000..3973a43cc7 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-msdu-buffer-types-handling-in-rx-err.patch @@ -0,0 +1,182 @@ +From 5c30e9dbe34703437c6fb2440c14ec9f843c9fce Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 30 Sep 2025 14:45:50 +0530 +Subject: wifi: ath12k: Fix MSDU buffer types handling in RX error path + +From: Sarika Sharma + +[ Upstream commit 36f9edbb9d0fc36c865c74f3c1ad8e1261ad3981 ] + +Currently, packets received on the REO exception ring from +unassociated peers are of MSDU buffer type, while the driver expects +link descriptor type packets. These packets are not parsed further due +to a return check on packet type in ath12k_hal_desc_reo_parse_err(), +but the associated skb is not freed. This may lead to kernel +crashes and buffer leaks. + +Hence to fix, update the RX error handler to explicitly drop +MSDU buffer type packets received on the REO exception ring. +This prevents further processing of invalid packets and ensures +stability in the RX error handling path. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Sarika Sharma +Reviewed-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20250930091551.3305312-2-sarika.sharma@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/dp_rx.c | 70 ++++++++++++++++++++++-- + drivers/net/wireless/ath/ath12k/hal_rx.c | 10 +--- + 2 files changed, 66 insertions(+), 14 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/dp_rx.c b/drivers/net/wireless/ath/ath12k/dp_rx.c +index 5e5c14a70316d..99d29eda26cf1 100644 +--- a/drivers/net/wireless/ath/ath12k/dp_rx.c ++++ b/drivers/net/wireless/ath/ath12k/dp_rx.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3781,6 +3781,48 @@ ath12k_dp_process_rx_err_buf(struct ath12k *ar, struct hal_reo_dest_ring *desc, + return 0; + } + ++static int ath12k_dp_h_msdu_buffer_type(struct ath12k_base *ab, ++ struct list_head *list, ++ struct hal_reo_dest_ring *desc) ++{ ++ struct ath12k_rx_desc_info *desc_info; ++ struct ath12k_skb_rxcb *rxcb; ++ struct sk_buff *msdu; ++ u64 desc_va; ++ ++ desc_va = (u64)le32_to_cpu(desc->buf_va_hi) << 32 | ++ le32_to_cpu(desc->buf_va_lo); ++ desc_info = (struct ath12k_rx_desc_info *)(uintptr_t)desc_va; ++ if (!desc_info) { ++ u32 cookie; ++ ++ cookie = le32_get_bits(desc->buf_addr_info.info1, ++ BUFFER_ADDR_INFO1_SW_COOKIE); ++ desc_info = ath12k_dp_get_rx_desc(ab, cookie); ++ if (!desc_info) { ++ ath12k_warn(ab, "Invalid cookie in manual descriptor retrieval: 0x%x\n", ++ cookie); ++ return -EINVAL; ++ } ++ } ++ ++ if (desc_info->magic != ATH12K_DP_RX_DESC_MAGIC) { ++ ath12k_warn(ab, "rx exception, magic check failed with value: %u\n", ++ desc_info->magic); ++ return -EINVAL; ++ } ++ ++ msdu = desc_info->skb; ++ desc_info->skb = NULL; ++ list_add_tail(&desc_info->list, list); ++ rxcb = ATH12K_SKB_RXCB(msdu); ++ dma_unmap_single(ab->dev, rxcb->paddr, msdu->len + skb_tailroom(msdu), ++ DMA_FROM_DEVICE); ++ dev_kfree_skb_any(msdu); ++ ++ return 0; ++} ++ + int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + int budget) + { +@@ -3825,6 +3867,26 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + drop = false; + ab->device_stats.err_ring_pkts++; + ++ hw_link_id = le32_get_bits(reo_desc->info0, ++ HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); ++ device_id = hw_links[hw_link_id].device_id; ++ partner_ab = ath12k_ag_to_ab(ag, device_id); ++ ++ /* Below case is added to handle data packet from un-associated clients. ++ * As it is expected that AST lookup will fail for ++ * un-associated station's data packets. ++ */ ++ if (le32_get_bits(reo_desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE) == ++ HAL_REO_DEST_RING_BUFFER_TYPE_MSDU) { ++ if (!ath12k_dp_h_msdu_buffer_type(partner_ab, ++ &rx_desc_used_list[device_id], ++ reo_desc)) { ++ num_buffs_reaped[device_id]++; ++ tot_n_bufs_reaped++; ++ } ++ goto next_desc; ++ } ++ + ret = ath12k_hal_desc_reo_parse_err(ab, reo_desc, &paddr, + &desc_bank); + if (ret) { +@@ -3833,11 +3895,6 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + continue; + } + +- hw_link_id = le32_get_bits(reo_desc->info0, +- HAL_REO_DEST_RING_INFO0_SRC_LINK_ID); +- device_id = hw_links[hw_link_id].device_id; +- partner_ab = ath12k_ag_to_ab(ag, device_id); +- + pdev_id = ath12k_hw_mac_id_to_pdev_id(partner_ab->hw_params, + hw_links[hw_link_id].pdev_idx); + ar = partner_ab->pdevs[pdev_id].ar; +@@ -3886,6 +3943,7 @@ int ath12k_dp_rx_process_err(struct ath12k_base *ab, struct napi_struct *napi, + } + } + ++next_desc: + if (tot_n_bufs_reaped >= quota) { + tot_n_bufs_reaped = quota; + goto exit; +diff --git a/drivers/net/wireless/ath/ath12k/hal_rx.c b/drivers/net/wireless/ath/ath12k/hal_rx.c +index 669096278fdd4..c4443ca05cd65 100644 +--- a/drivers/net/wireless/ath/ath12k/hal_rx.c ++++ b/drivers/net/wireless/ath/ath12k/hal_rx.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include "debug.h" +@@ -323,7 +323,7 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, + { + enum hal_reo_dest_ring_push_reason push_reason; + enum hal_reo_dest_ring_error_code err_code; +- u32 cookie, val; ++ u32 cookie; + + push_reason = le32_get_bits(desc->info0, + HAL_REO_DEST_RING_INFO0_PUSH_REASON); +@@ -338,12 +338,6 @@ int ath12k_hal_desc_reo_parse_err(struct ath12k_base *ab, + return -EINVAL; + } + +- val = le32_get_bits(desc->info0, HAL_REO_DEST_RING_INFO0_BUFFER_TYPE); +- if (val != HAL_REO_DEST_RING_BUFFER_TYPE_LINK_DESC) { +- ath12k_warn(ab, "expected buffer type link_desc"); +- return -EINVAL; +- } +- + ath12k_hal_rx_reo_ent_paddr_get(ab, &desc->buf_addr_info, paddr, &cookie); + *desc_bank = u32_get_bits(cookie, DP_LINK_DESC_BANK_MASK); + +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch b/queue-6.18/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch new file mode 100644 index 0000000000..356083d312 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-potential-memory-leak-in-ath12k_wow_.patch @@ -0,0 +1,39 @@ +From d4ce7d753cd2ff66b70b806059553a369a95db49 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:34:55 +0530 +Subject: wifi: ath12k: fix potential memory leak in + ath12k_wow_arp_ns_offload() + +From: Abdun Nihaal + +[ Upstream commit be5febd51c478bc8e24ad3480435f2754a403b14 ] + +When the call to ath12k_wmi_arp_ns_offload() fails, the temporary memory +allocation for offload is not freed before returning. Fix that by +freeing offload in the error path. + +Fixes: 1666108c74c4 ("wifi: ath12k: support ARP and NS offload") +Signed-off-by: Abdun Nihaal +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251028170457.134608-1-nihaal@cse.iitm.ac.in +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/wow.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/net/wireless/ath/ath12k/wow.c b/drivers/net/wireless/ath/ath12k/wow.c +index dce9bd0bcaefb..e8481626f1940 100644 +--- a/drivers/net/wireless/ath/ath12k/wow.c ++++ b/drivers/net/wireless/ath/ath12k/wow.c +@@ -758,6 +758,7 @@ static int ath12k_wow_arp_ns_offload(struct ath12k *ar, bool enable) + if (ret) { + ath12k_warn(ar->ab, "failed to set arp ns offload vdev %i: enable %d, ret %d\n", + arvif->vdev_id, enable, ret); ++ kfree(offload); + return ret; + } + } +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-reusing-m3-memory.patch b/queue-6.18/wifi-ath12k-fix-reusing-m3-memory.patch new file mode 100644 index 0000000000..557925b2c1 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-reusing-m3-memory.patch @@ -0,0 +1,107 @@ +From eba3255ac16528b5fe15686d5491e0e00e214e52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:07:14 +0800 +Subject: wifi: ath12k: fix reusing m3 memory + +From: Baochen Qiang + +[ Upstream commit 00575bb44b2c2aa53d0a768de2b80c9c1af0174d ] + +During firmware recovery or suspend/resume, m3 memory could be reused if +the size of the new m3 binary is equal to or less than that of the +existing memory. There will be issues for the latter case, since +m3_mem->size will be updated with a smaller value and this value is +eventually used in the free path, where the original total size should be +used instead. + +To fix it, add a new member in m3_mem_region structure to track the original +memory size and use it in free path. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00302-QCAHMTSWPL_V1.0_V2.0_SILICONZ-1.115823.3 + +Fixes: 05090ae82f44 ("wifi: ath12k: check M3 buffer size as well whey trying to reuse it") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251029-ath12k-fix-m3-reuse-v1-1-69225bacfc5d@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/qmi.c | 11 +++++++---- + drivers/net/wireless/ath/ath12k/qmi.h | 5 ++++- + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/qmi.c b/drivers/net/wireless/ath/ath12k/qmi.c +index 36325e62aa242..8de9aee2498ec 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.c ++++ b/drivers/net/wireless/ath/ath12k/qmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -3114,9 +3114,10 @@ static void ath12k_qmi_m3_free(struct ath12k_base *ab) + if (!m3_mem->vaddr) + return; + +- dma_free_coherent(ab->dev, m3_mem->size, ++ dma_free_coherent(ab->dev, m3_mem->total_size, + m3_mem->vaddr, m3_mem->paddr); + m3_mem->vaddr = NULL; ++ m3_mem->total_size = 0; + m3_mem->size = 0; + } + +@@ -3152,7 +3153,7 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + + /* In recovery/resume cases, M3 buffer is not freed, try to reuse that */ + if (m3_mem->vaddr) { +- if (m3_mem->size >= m3_len) ++ if (m3_mem->total_size >= m3_len) + goto skip_m3_alloc; + + /* Old buffer is too small, free and reallocate */ +@@ -3164,11 +3165,13 @@ static int ath12k_qmi_m3_load(struct ath12k_base *ab) + GFP_KERNEL); + if (!m3_mem->vaddr) { + ath12k_err(ab, "failed to allocate memory for M3 with size %zu\n", +- fw->size); ++ m3_len); + ret = -ENOMEM; + goto out; + } + ++ m3_mem->total_size = m3_len; ++ + 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 4767d9a2e309e..7a88268aa1e9e 100644 +--- a/drivers/net/wireless/ath/ath12k/qmi.h ++++ b/drivers/net/wireless/ath/ath12k/qmi.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: BSD-3-Clause-Clear */ + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #ifndef ATH12K_QMI_H +@@ -120,6 +120,9 @@ struct target_info { + }; + + struct m3_mem_region { ++ /* total memory allocated */ ++ u32 total_size; ++ /* actual memory being used */ + u32 size; + dma_addr_t paddr; + void *vaddr; +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch b/queue-6.18/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch new file mode 100644 index 0000000000..0ff4ee74d7 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-timeout-error-during-beacon-stats-re.patch @@ -0,0 +1,102 @@ +From 382475fd8b054c5b1f590504bb9c839a6572ea4c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 08:37:46 +0530 +Subject: wifi: ath12k: Fix timeout error during beacon stats retrieval + +From: Manish Dharanenthiran + +[ Upstream commit 2977567b244f056d86658160659f06cd6c78ba3d ] + +Currently, for beacon_stats, ath12k_mac_get_fw_stats() is called +for each started BSS on the specified hardware. +ath12k_mac_get_fw_stats() will wait for the fw_stats_done completion +after fetching the requested data from firmware. For the beacon_stats, +fw_stats_done completion will be set only when stats are received for +all BSSes. However, for other stats like vdev_stats or pdev_stats, there +is one request to the firmware for all enabled BSSes. Since beacon_stats +is fetched individually for all BSSes enabled in that pdev, waiting for +the completion event results in a timeout error when multiple BSSes are +enabled. + +Avoid this by completing the fw_stats_done immediately after +updating the requested BSS's beacon stats in the list. Subsequently, +this list will be used to display the beacon stats for all enabled +BSSes in the requested pdev. + +Additionally, remove 'num_bcn_recvd' from the ath12k_fw_stats struct +as it is no longer needed. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 9fe4669ae919 ("wifi: ath12k: Request beacon stats from firmware") +Signed-off-by: Manish Dharanenthiran +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251031-beacon_stats-v1-2-f52fce7b03ac@qti.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/core.c | 2 -- + drivers/net/wireless/ath/ath12k/core.h | 1 - + drivers/net/wireless/ath/ath12k/wmi.c | 10 +--------- + 3 files changed, 1 insertion(+), 12 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/core.c b/drivers/net/wireless/ath/ath12k/core.c +index a2137b363c2fe..cc352eef19399 100644 +--- a/drivers/net/wireless/ath/ath12k/core.c ++++ b/drivers/net/wireless/ath/ath12k/core.c +@@ -1,7 +1,6 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +@@ -1250,7 +1249,6 @@ void ath12k_fw_stats_reset(struct ath12k *ar) + spin_lock_bh(&ar->data_lock); + ath12k_fw_stats_free(&ar->fw_stats); + ar->fw_stats.num_vdev_recvd = 0; +- ar->fw_stats.num_bcn_recvd = 0; + spin_unlock_bh(&ar->data_lock); + } + +diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h +index 3d1956966a485..d7688b383f62c 100644 +--- a/drivers/net/wireless/ath/ath12k/core.h ++++ b/drivers/net/wireless/ath/ath12k/core.h +@@ -644,7 +644,6 @@ struct ath12k_fw_stats { + struct list_head vdevs; + struct list_head bcn; + u32 num_vdev_recvd; +- u32 num_bcn_recvd; + }; + + struct ath12k_dbg_htt_stats { +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index e76275bd6916f..e647b842a6a1c 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -8418,18 +8418,10 @@ static void ath12k_wmi_fw_stats_process(struct ath12k *ar, + ath12k_warn(ab, "empty beacon stats"); + return; + } +- /* Mark end until we reached the count of all started VDEVs +- * within the PDEV +- */ +- if (ar->num_started_vdevs) +- is_end = ((++ar->fw_stats.num_bcn_recvd) == +- ar->num_started_vdevs); + + list_splice_tail_init(&stats->bcn, + &ar->fw_stats.bcn); +- +- if (is_end) +- complete(&ar->fw_stats_done); ++ complete(&ar->fw_stats_done); + } + } + +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch b/queue-6.18/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch new file mode 100644 index 0000000000..1f25796c55 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-tx-and-rx-mcs-rate-configurations-in.patch @@ -0,0 +1,58 @@ +From 46bf0b335d29924c45d8749855ad951caae032c9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:16:56 -0700 +Subject: wifi: ath12k: fix TX and RX MCS rate configurations in HE mode + +From: Pradeep Kumar Chitrapu + +[ Upstream commit 9c5f229b1312a31aff762b2111f6751e4e3722fe ] + +Currently, the TX and RX MCS rate configurations per peer are +reversed when sent to the firmware. As a result, RX MCS rates +are configured for TX, and vice versa. This commit rectifies +the configuration to match what the firmware expects. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Pradeep Kumar Chitrapu +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251009211656.2386085-3-quic_pradeepc@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 4e6d136433202..0cec6c47fca29 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -2624,9 +2624,10 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, + switch (link_sta->bandwidth) { + case IEEE80211_STA_RX_BW_160: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + +- v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); ++ v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2636,10 +2637,10 @@ static void ath12k_peer_assoc_h_he(struct ath12k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath12k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-fix-vht-mcs-assignment.patch b/queue-6.18/wifi-ath12k-fix-vht-mcs-assignment.patch new file mode 100644 index 0000000000..aa6cb8bde0 --- /dev/null +++ b/queue-6.18/wifi-ath12k-fix-vht-mcs-assignment.patch @@ -0,0 +1,114 @@ +From 7fd38d313a6a9fd96349252a8a277720f35ae50a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 14:16:55 -0700 +Subject: wifi: ath12k: fix VHT MCS assignment + +From: Baochen Qiang + +[ Upstream commit 8c21b32c2cc82224c7fc1a9f67318f3b1199744b ] + +While associating, firmware needs the peer's receive capability +to calculate its own VHT transmit MCS. Currently, the host +sends this information via mcs->rx_mcs_set field, but firmware +actually reads it from mcs->tx_mcs_set field. This mismatch is +incorrect. + +This issue has not caused failures so far because most peers +advertise identical TX and RX capabilities. Fix this by +assigning the value to tx_mcs_set as expected. + +Additionally, the rate control mask is intended to limit our +transmit MCS, so it should also apply to the peer's receive +capability. Update the logic accordingly. + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Baochen Qiang +Signed-off-by: Pradeep Kumar Chitrapu +Reviewed-by: Vasanthakumar Thiagarajan +Reviewed-by: Baochen Qiang +Link: https://patch.msgid.link/20251009211656.2386085-2-quic_pradeepc@quicinc.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 7 +++---- + drivers/net/wireless/ath/ath12k/wmi.c | 13 ++++++++----- + drivers/net/wireless/ath/ath12k/wmi.h | 2 ++ + 3 files changed, 13 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index db351c9220181..4e6d136433202 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -2249,7 +2249,6 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, + struct cfg80211_chan_def def; + enum nl80211_band band; + u16 *vht_mcs_mask; +- u16 tx_mcs_map; + u8 ampdu_factor; + u8 max_nss, vht_mcs; + int i, vht_nss, nss_idx; +@@ -2340,10 +2339,10 @@ static void ath12k_peer_assoc_h_vht(struct ath12k *ar, + arg->peer_nss = min(link_sta->rx_nss, max_nss); + arg->rx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.rx_highest); + arg->rx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.rx_mcs_map); +- arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); ++ arg->rx_mcs_set = ath12k_peer_assoc_h_vht_limit(arg->rx_mcs_set, vht_mcs_mask); + +- tx_mcs_map = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); +- arg->tx_mcs_set = ath12k_peer_assoc_h_vht_limit(tx_mcs_map, vht_mcs_mask); ++ arg->tx_max_rate = __le16_to_cpu(vht_cap->vht_mcs.tx_highest); ++ arg->tx_mcs_set = __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); + + /* In QCN9274 platform, VHT MCS rate 10 and 11 is enabled by default. + * VHT MCS rate 10 and 11 is not supported in 11ac standard. +diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c +index ff6b3d4ea8208..e76275bd6916f 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.c ++++ b/drivers/net/wireless/ath/ath12k/wmi.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + #include + #include +@@ -2367,10 +2367,13 @@ int ath12k_wmi_send_peer_assoc_cmd(struct ath12k *ar, + cmd->peer_bw_rxnss_override |= cpu_to_le32(arg->peer_bw_rxnss_override); + + if (arg->vht_capable) { +- mcs->rx_max_rate = cpu_to_le32(arg->rx_max_rate); +- mcs->rx_mcs_set = cpu_to_le32(arg->rx_mcs_set); +- mcs->tx_max_rate = cpu_to_le32(arg->tx_max_rate); +- mcs->tx_mcs_set = cpu_to_le32(arg->tx_mcs_set); ++ /* Firmware interprets mcs->tx_mcs_set field as peer's ++ * RX capability ++ */ ++ mcs->rx_max_rate = cpu_to_le32(arg->tx_max_rate); ++ mcs->rx_mcs_set = cpu_to_le32(arg->tx_mcs_set); ++ mcs->tx_max_rate = cpu_to_le32(arg->rx_max_rate); ++ mcs->tx_mcs_set = cpu_to_le32(arg->rx_mcs_set); + } + + /* HE Rates */ +diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h +index a8c3190e8ad95..6d9c645e3d5d0 100644 +--- a/drivers/net/wireless/ath/ath12k/wmi.h ++++ b/drivers/net/wireless/ath/ath12k/wmi.h +@@ -4218,8 +4218,10 @@ struct wmi_unit_test_cmd { + struct ath12k_wmi_vht_rate_set_params { + __le32 tlv_header; + __le32 rx_max_rate; ++ /* MCS at which the peer can transmit */ + __le32 rx_mcs_set; + __le32 tx_max_rate; ++ /* MCS at which the peer can receive */ + __le32 tx_mcs_set; + __le32 tx_max_mcs_nss; + } __packed; +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-restore-register-window-after-global-res.patch b/queue-6.18/wifi-ath12k-restore-register-window-after-global-res.patch new file mode 100644 index 0000000000..85fbd5d4ea --- /dev/null +++ b/queue-6.18/wifi-ath12k-restore-register-window-after-global-res.patch @@ -0,0 +1,91 @@ +From bec37062b19a7fd456b285d7bc8acb14ac5adfe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 10:36:36 +0800 +Subject: wifi: ath12k: restore register window after global reset + +From: Baochen Qiang + +[ Upstream commit a41281f6518e485220d180a6031d302a736fc463 ] + +Hardware target implements an address space larger than that PCI BAR can +map. In order to be able to access the whole target address space, the +BAR space is split into 4 segments, of which the last 3, called windows, +can be dynamically mapped to the desired area. This is achieved by +updating WINDOW_REG_ADDRESS register with appropriate window value. +Currently each time when accessing a register that beyond WINDOW_START, +host calculates the window value and caches it after window update, +this way next time when accessing a register falling in the same window, +host knows that the window is already good hence no additional update +needed. + +However this mechanism breaks after global reset is triggered in +ath12k_pci_soc_global_reset(), because with global reset hardware resets +WINDOW_REG_ADDRESS register hence the window is not properly mapped any +more. Current host does nothing about this, as a result a subsequent +register access may not work as expected if it falls in a window same as +before. + +Although there is no obvious issue seen now, better to fix it to avoid +future problem. The fix is done by restoring the window register after +global reset. + +Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.1.c5-00284.1-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 + +Fixes: d889913205cf ("wifi: ath12k: driver for Qualcomm Wi-Fi 7 devices") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath12k-reset-window-cache-v1-1-29e0e751deed@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/pci.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/pci.c b/drivers/net/wireless/ath/ath12k/pci.c +index c729d5526c753..60b8f7361b7f6 100644 +--- a/drivers/net/wireless/ath/ath12k/pci.c ++++ b/drivers/net/wireless/ath/ath12k/pci.c +@@ -1,7 +1,7 @@ + // SPDX-License-Identifier: BSD-3-Clause-Clear + /* + * Copyright (c) 2019-2021 The Linux Foundation. All rights reserved. +- * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved. ++ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + + #include +@@ -218,6 +218,19 @@ static inline bool ath12k_pci_is_offset_within_mhi_region(u32 offset) + return (offset >= PCI_MHIREGLEN_REG && offset <= PCI_MHI_REGION_END); + } + ++static void ath12k_pci_restore_window(struct ath12k_base *ab) ++{ ++ struct ath12k_pci *ab_pci = ath12k_pci_priv(ab); ++ ++ spin_lock_bh(&ab_pci->window_lock); ++ ++ iowrite32(WINDOW_ENABLE_BIT | ab_pci->register_window, ++ ab->mem + WINDOW_REG_ADDRESS); ++ ioread32(ab->mem + WINDOW_REG_ADDRESS); ++ ++ spin_unlock_bh(&ab_pci->window_lock); ++} ++ + static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) + { + u32 val, delay; +@@ -242,6 +255,11 @@ static void ath12k_pci_soc_global_reset(struct ath12k_base *ab) + val = ath12k_pci_read32(ab, PCIE_SOC_GLOBAL_RESET); + if (val == 0xffffffff) + ath12k_warn(ab, "link down error during global reset\n"); ++ ++ /* Restore window register as its content is cleared during ++ * hardware global reset, such that it aligns with host cache. ++ */ ++ ath12k_pci_restore_window(ab); + } + + static void ath12k_pci_clear_dbg_registers(struct ath12k_base *ab) +-- +2.51.0 + diff --git a/queue-6.18/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch b/queue-6.18/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch new file mode 100644 index 0000000000..7cf6cd888a --- /dev/null +++ b/queue-6.18/wifi-ath12k-unassign-arvif-on-scan-vdev-create-failu.patch @@ -0,0 +1,57 @@ +From b9ab07b4e602e6f4f9ec21660679d8031e51b4f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 26 Oct 2025 23:52:54 +0530 +Subject: wifi: ath12k: unassign arvif on scan vdev create failure + +From: Rameshkumar Sundaram + +[ Upstream commit e70515039d44be61b6a73aafb401d141b0034d12 ] + +During scan and remain-on-channel requests, a scan link vif (arvif) is +assigned and a temporary vdev is created. If vdev creation fails, the +assigned arvif is left attached until the virtual interface is removed, +leaving a stale link in ahvif. + +Fix this by freeing the stale arvif and resetting the corresponding link in +ahvif by calling ath12k_mac_unassign_link_vif() when vdev creation fails. + +While at it, propagate the actual error code from ath12k_mac_vdev_create() +instead of returning -EINVAL in ath12k_mac_initiate_hw_scan(). + +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO") +Signed-off-by: Rameshkumar Sundaram +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251026182254.1399650-3-rameshkumar.sundaram@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath12k/mac.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c +index 8f139505019c4..095b49a39683c 100644 +--- a/drivers/net/wireless/ath/ath12k/mac.c ++++ b/drivers/net/wireless/ath/ath12k/mac.c +@@ -5059,7 +5059,8 @@ static int ath12k_mac_initiate_hw_scan(struct ieee80211_hw *hw, + ret = ath12k_mac_vdev_create(ar, arvif); + if (ret) { + ath12k_warn(ar->ab, "unable to create scan vdev %d\n", ret); +- return -EINVAL; ++ ath12k_mac_unassign_link_vif(arvif); ++ return ret; + } + } + +@@ -12895,6 +12896,7 @@ static int ath12k_mac_op_remain_on_channel(struct ieee80211_hw *hw, + if (ret) { + ath12k_warn(ar->ab, "unable to create scan vdev for roc: %d\n", + ret); ++ ath12k_mac_unassign_link_vif(arvif); + return ret; + } + } +-- +2.51.0 + diff --git a/queue-6.18/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-6.18/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..bf1d25814b --- /dev/null +++ b/queue-6.18/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From 5a78e70699cb831768545098672cbebb76d3714c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 3b4ded2ac801c..37232ee220375 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-6.18/wifi-ieee80211-correct-fils-status-codes.patch b/queue-6.18/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..9a53c34592 --- /dev/null +++ b/queue-6.18/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From 145599f46c10f1fcd7d7591fac2c3adc0adeb73d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index ddff9102f6332..1f4679092e69d 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3594,8 +3594,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + WLAN_STATUS_DENIED_TID_TO_LINK_MAPPING = 133, +-- +2.51.0 + diff --git a/queue-6.18/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch b/queue-6.18/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch new file mode 100644 index 0000000000..7130704c31 --- /dev/null +++ b/queue-6.18/wifi-iwlwifi-mld-add-null-check-for-kzalloc-in-iwl_m.patch @@ -0,0 +1,41 @@ +From e22930ea27af185cbf095e8ef0b94a361703ad3e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 12:11:28 +0800 +Subject: wifi: iwlwifi: mld: add null check for kzalloc() in + iwl_mld_send_proto_offload() + +From: Li Qiang + +[ Upstream commit 3df28496673bd8009f1cd3a85a63650c96e369f4 ] + +Add a missing NULL pointer check after kzalloc() in +iwl_mld_send_proto_offload(). Without this check, a failed +allocation could lead to a NULL dereference. + +Fixes: d1e879ec600f9 ("wifi: iwlwifi: add iwlmld sub-driver") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251017041128.1379715-1-liqiang01@kylinos.cn +Signed-off-by: Miri Korenblit +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/intel/iwlwifi/mld/d3.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/intel/iwlwifi/mld/d3.c b/drivers/net/wireless/intel/iwlwifi/mld/d3.c +index 1d4282a21f09e..dd85be94433cc 100644 +--- a/drivers/net/wireless/intel/iwlwifi/mld/d3.c ++++ b/drivers/net/wireless/intel/iwlwifi/mld/d3.c +@@ -1794,6 +1794,10 @@ iwl_mld_send_proto_offload(struct iwl_mld *mld, + u32 enabled = 0; + + cmd = kzalloc(hcmd.len[0], GFP_KERNEL); ++ if (!cmd) { ++ IWL_DEBUG_WOWLAN(mld, "Failed to allocate proto offload cmd\n"); ++ return -ENOMEM; ++ } + + #if IS_ENABLED(CONFIG_IPV6) + struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(vif); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch b/queue-6.18/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch new file mode 100644 index 0000000000..99031c3116 --- /dev/null +++ b/queue-6.18/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch @@ -0,0 +1,196 @@ +From 47aef478e2678c83db46a9e8d04f160c7d6a2175 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:05:07 +0800 +Subject: wifi: mac80211: fix CMAC functions not handling errors + +From: Chien Wong + +[ Upstream commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb ] + +The called hash functions could fail thus we should check return values. + +Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver") +Signed-off-by: Chien Wong +Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ + net/mac80211/aes_cmac.h | 8 +++--- + net/mac80211/wpa.c | 20 +++++++------ + 3 files changed, 61 insertions(+), 30 deletions(-) + +diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c +index 48c04f89de20a..65989c7dfc680 100644 +--- a/net/mac80211/aes_cmac.c ++++ b/net/mac80211/aes_cmac.c +@@ -22,50 +22,77 @@ + + static const u8 zero[CMAC_TLEN_256]; + +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + u8 out[AES_BLOCK_SIZE]; + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN); ++ err = crypto_shash_update(desc, data, ++ data_len - CMAC_TLEN); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN, out); +- ++ err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); ++ if (err) ++ return err; + memcpy(mic, out, CMAC_TLEN); ++ ++ return 0; + } + +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, +- data_len - 8 - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN_256); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); ++ return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); + } + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h +index 76817446fb838..f74150542142a 100644 +--- a/net/mac80211/aes_cmac.h ++++ b/net/mac80211/aes_cmac.h +@@ -11,10 +11,10 @@ + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len); +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); + void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); + + #endif /* AES_CMAC_H */ +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 40d5d9e484791..bb0fa505cdcae 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -869,8 +869,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) + /* + * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) + */ +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -916,8 +917,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) + + /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) + */ +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -956,8 +958,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +@@ -1006,8 +1009,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-move-mt76_abort_scan-out-of-mt76_reset_dev.patch b/queue-6.18/wifi-mt76-move-mt76_abort_scan-out-of-mt76_reset_dev.patch new file mode 100644 index 0000000000..62021b6f9f --- /dev/null +++ b/queue-6.18/wifi-mt76-move-mt76_abort_scan-out-of-mt76_reset_dev.patch @@ -0,0 +1,68 @@ +From 22e432eebd9039b8f72b52a888729b1dd94a033d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:16:23 +0100 +Subject: wifi: mt76: Move mt76_abort_scan out of mt76_reset_device() + +From: Lorenzo Bianconi + +[ Upstream commit 6aaaaeacf18b2dc2b0f78f241800e0ea680938c7 ] + +Move mt76_abort_scan routine out of mt76_reset_device() in order to +avoid a possible deadlock since mt76_reset_device routine is running +with mt76 mutex help and mt76_abort_scan_complete() can grab mt76 mutex +in some cases. + +Fixes: b36d55610215a ("wifi: mt76: abort scan/roc on hw restart") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251114-mt76-fix-missing-mtx-v1-3-259ebf11f654@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mac80211.c | 2 -- + drivers/net/wireless/mediatek/mt76/mt7915/mac.c | 2 ++ + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 ++ + 3 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c +index 5ceaf78c9ea06..5e75861bf6f99 100644 +--- a/drivers/net/wireless/mediatek/mt76/mac80211.c ++++ b/drivers/net/wireless/mediatek/mt76/mac80211.c +@@ -847,8 +847,6 @@ void mt76_reset_device(struct mt76_dev *dev) + } + rcu_read_unlock(); + +- mt76_abort_scan(dev); +- + INIT_LIST_HEAD(&dev->wcid_list); + INIT_LIST_HEAD(&dev->sta_poll_list); + dev->vif_mask = 0; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +index 1c0d310146d63..5caf818e82834 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c +@@ -1451,6 +1451,8 @@ mt7915_mac_full_reset(struct mt7915_dev *dev) + if (ext_phy) + cancel_delayed_work_sync(&ext_phy->mac_work); + ++ mt76_abort_scan(&dev->mt76); ++ + mutex_lock(&dev->mt76.mutex); + for (i = 0; i < 10; i++) { + if (!mt7915_mac_restart(dev)) +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index b06728a98a691..cfad46a532bb7 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -2424,6 +2424,8 @@ mt7996_mac_full_reset(struct mt7996_dev *dev) + mt7996_for_each_phy(dev, phy) + cancel_delayed_work_sync(&phy->mt76->mac_work); + ++ mt76_abort_scan(&dev->mt76); ++ + mutex_lock(&dev->mt76.mutex); + for (i = 0; i < 10; i++) { + if (!mt7996_mac_restart(dev)) +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch b/queue-6.18/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch new file mode 100644 index 0000000000..d4d96d2da2 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-add-missing-locking-in-mt7996_mac_s.patch @@ -0,0 +1,46 @@ +From f0221c33d32ff698d2e8967065245c036b3f4bef Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 10:30:26 +0100 +Subject: wifi: mt76: mt7996: Add missing locking in mt7996_mac_sta_rc_work() + +From: Lorenzo Bianconi + +[ Upstream commit 7545551631fa63101f97974f49ac0b564814f703 ] + +Grab the mt76 mutex running mt7996_mac_sta_rc_work() since it is +required by mt7996_mcu_add_rate_ctrl routine. + +Fixes: 28d519d0d493a ("wifi: mt76: Move RCU section in mt7996_mcu_add_rate_ctrl_fixed()") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251118-mt7996-rc-work-missing-mtx-v1-1-0739c493a6cb@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index cfad46a532bb7..502136691a69e 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -2860,6 +2860,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) + LIST_HEAD(list); + u32 changed; + ++ mutex_lock(&dev->mt76.mutex); ++ + spin_lock_bh(&dev->mt76.sta_poll_lock); + list_splice_init(&dev->sta_rc_list, &list); + +@@ -2892,6 +2894,8 @@ void mt7996_mac_sta_rc_work(struct work_struct *work) + } + + spin_unlock_bh(&dev->mt76.sta_poll_lock); ++ ++ mutex_unlock(&dev->mt76.mutex); + } + + void mt7996_mac_work(struct work_struct *work) +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-emi-rings-for-rro.patch b/queue-6.18/wifi-mt76-mt7996-fix-emi-rings-for-rro.patch new file mode 100644 index 0000000000..f693b01c58 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-emi-rings-for-rro.patch @@ -0,0 +1,100 @@ +From 70384f71438040804056e9d2626db12a3a3466c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:03 +0800 +Subject: wifi: mt76: mt7996: fix EMI rings for RRO + +From: Shayne Chen + +[ Upstream commit a4031fec9d0d230224a7edcefa3368c06c317148 ] + +The RRO EMI rings only need to be allocated when WED is not active. +This patch fixes command timeout issue for the setting of WED off and +RRO on. + +Fixes: 3a29164425e9 ("wifi: mt76: mt7996: Add SW path for HW-RRO v3.1") +Co-developed-by: Rex Lu +Signed-off-by: Rex Lu +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-12-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/dma.c | 15 +++++++++------ + .../net/wireless/mediatek/mt76/mt7996/init.c | 19 ++++++++++++++++--- + 2 files changed, 25 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +index 659015f93d323..7ed2f21b0e6db 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/dma.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/dma.c +@@ -512,12 +512,15 @@ int mt7996_dma_rro_init(struct mt7996_dev *dev) + if (ret) + return ret; + +- /* We need to set cpu idx pointer before resetting the EMI +- * queues. +- */ +- mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx = +- &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx; +- mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], true); ++ if (!mtk_wed_device_active(&mdev->mmio.wed)) { ++ /* We need to set cpu idx pointer before resetting the ++ * EMI queues. ++ */ ++ mdev->q_rx[MT_RXQ_RRO_RXDMAD_C].emi_cpu_idx = ++ &dev->wed_rro.emi_rings_cpu.ptr->ring[0].idx; ++ mt76_queue_reset(dev, &mdev->q_rx[MT_RXQ_RRO_RXDMAD_C], ++ true); ++ } + goto start_hw_rro; + } + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/init.c b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +index 5e95a36b42d16..b136b9a669769 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/init.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/init.c +@@ -959,9 +959,10 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev) + MT7996_RRO_MSDU_PG_SIZE_PER_CR); + } + +- if (dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) { ++ if (!mtk_wed_device_active(&dev->mt76.mmio.wed) && ++ dev->mt76.hwrro_mode == MT76_HWRRO_V3_1) { + ptr = dmam_alloc_coherent(dev->mt76.dma_dev, +- sizeof(dev->wed_rro.emi_rings_cpu.ptr), ++ sizeof(*dev->wed_rro.emi_rings_cpu.ptr), + &dev->wed_rro.emi_rings_cpu.phy_addr, + GFP_KERNEL); + if (!ptr) +@@ -970,7 +971,7 @@ static int mt7996_wed_rro_init(struct mt7996_dev *dev) + dev->wed_rro.emi_rings_cpu.ptr = ptr; + + ptr = dmam_alloc_coherent(dev->mt76.dma_dev, +- sizeof(dev->wed_rro.emi_rings_dma.ptr), ++ sizeof(*dev->wed_rro.emi_rings_dma.ptr), + &dev->wed_rro.emi_rings_dma.phy_addr, + GFP_KERNEL); + if (!ptr) +@@ -1036,6 +1037,18 @@ static void mt7996_wed_rro_free(struct mt7996_dev *dev) + dev->wed_rro.msdu_pg[i].phy_addr); + } + ++ if (dev->wed_rro.emi_rings_cpu.ptr) ++ dmam_free_coherent(dev->mt76.dma_dev, ++ sizeof(*dev->wed_rro.emi_rings_cpu.ptr), ++ dev->wed_rro.emi_rings_cpu.ptr, ++ dev->wed_rro.emi_rings_cpu.phy_addr); ++ ++ if (dev->wed_rro.emi_rings_dma.ptr) ++ dmam_free_coherent(dev->mt76.dma_dev, ++ sizeof(*dev->wed_rro.emi_rings_dma.ptr), ++ dev->wed_rro.emi_rings_dma.ptr, ++ dev->wed_rro.emi_rings_dma.phy_addr); ++ + if (!dev->wed_rro.session.ptr) + return; + +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch b/queue-6.18/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch new file mode 100644 index 0000000000..8c0ee93279 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-implicit-beamforming-support-fo.patch @@ -0,0 +1,41 @@ +From 3dba7aa709c2ea1e071e603378e66f9b561102b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:54 +0800 +Subject: wifi: mt76: mt7996: fix implicit beamforming support for mt7992 + +From: Howard Hsu + +[ Upstream commit 5d86765828b47444908a8689f2625872e8dac48f ] + +Fix the ibf_timeout field for mt7996, mt7992 and mt7990 chipsets. For +the mt7992, this value shall be set as 0xff, while the others shall be +set as 0x18. + +Fixes: ad4c9a8a9803 ("wifi: mt76: mt7996: add implicit beamforming support for mt7992") +Signed-off-by: Howard Hsu +Signed-off-by: Shayne Chen +Link: https://patch.msgid.link/20251106064203.1000505-3-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index afa6a43bd51e5..9af3c48707ab7 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -1822,8 +1822,8 @@ mt7996_mcu_sta_bfer_tlv(struct mt7996_dev *dev, struct sk_buff *skb, + bf->ibf_nrow = tx_ant; + + if (link_sta->eht_cap.has_eht || link_sta->he_cap.has_he) +- bf->ibf_timeout = is_mt7996(&dev->mt76) ? MT7996_IBF_TIMEOUT : +- MT7992_IBF_TIMEOUT; ++ bf->ibf_timeout = is_mt7992(&dev->mt76) ? MT7992_IBF_TIMEOUT : ++ MT7996_IBF_TIMEOUT; + else if (!ebf && link_sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->ncol) + bf->ibf_timeout = MT7996_IBF_TIMEOUT_LEGACY; + else +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch b/queue-6.18/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch new file mode 100644 index 0000000000..e20217cd94 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-max-nss-value-when-getting-rx-c.patch @@ -0,0 +1,39 @@ +From f972a27dd4409e8b483f6e83287f1dd2526d921a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:52 +0800 +Subject: wifi: mt76: mt7996: fix max nss value when getting rx chainmask + +From: StanleyYP Wang + +[ Upstream commit 361b59b6be7c33c43b619d5cada394efc0f3b398 ] + +Since wiphy->available_antennas_tx now accumulates the chainmask of all +the radios of a wiphy, use phy->orig_antenna_mask to get the original +max nss for comparison. + +Fixes: 69d54ce7491d ("wifi: mt76: mt7996: switch to single multi-radio wiphy") +Signed-off-by: StanleyYP Wang +Signed-off-by: Shayne Chen +Link: https://patch.msgid.link/20251106064203.1000505-1-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +index 718e4d4ad85f2..1727e73a99ce6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +@@ -786,7 +786,7 @@ void mt7996_memcpy_fromio(struct mt7996_dev *dev, void *buf, u32 offset, + + static inline u16 mt7996_rx_chainmask(struct mt7996_phy *phy) + { +- int max_nss = hweight8(phy->mt76->hw->wiphy->available_antennas_tx); ++ int max_nss = hweight16(phy->orig_antenna_mask); + int cur_nss = hweight8(phy->mt76->antenna_mask); + u16 tx_chainmask = phy->mt76->chainmask; + +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch b/queue-6.18/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch new file mode 100644 index 0000000000..7eb9434f43 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-mld-group-index-assignment.patch @@ -0,0 +1,123 @@ +From 261148adc6a261f4e884e5ccef0019e7cacc3fc3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:00 +0800 +Subject: wifi: mt76: mt7996: fix MLD group index assignment + +From: Shayne Chen + +[ Upstream commit 4fb3b4e7d1ca5453c6167816230370afc15f26bf ] + +Fix extender mode and MBSS issues caused by incorrect assignment of the +MLD group and remap indices. + +Fixes: ed01c310eca9 ("wifi: mt76: mt7996: Fix mt7996_mcu_bss_mld_tlv routine") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-9-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/main.c | 58 +++++++++++++------ + 1 file changed, 40 insertions(+), 18 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 4e73854589558..dc0fcf5cb7fb1 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -90,9 +90,11 @@ static void mt7996_stop(struct ieee80211_hw *hw, bool suspend) + { + } + +-static inline int get_free_idx(u32 mask, u8 start, u8 end) ++static inline int get_free_idx(u64 mask, u8 start, u8 end) + { +- return ffs(~mask & GENMASK(end, start)); ++ if (~mask & GENMASK_ULL(end, start)) ++ return __ffs64(~mask & GENMASK_ULL(end, start)) + 1; ++ return 0; + } + + static int get_omac_idx(enum nl80211_iftype type, u64 mask) +@@ -308,12 +310,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + if (idx < 0) + return -ENOSPC; + +- if (!dev->mld_idx_mask) { /* first link in the group */ +- mvif->mld_group_idx = get_own_mld_idx(dev->mld_idx_mask, true); +- mvif->mld_remap_idx = get_free_idx(dev->mld_remap_idx_mask, +- 0, 15); +- } +- + mld_idx = get_own_mld_idx(dev->mld_idx_mask, false); + if (mld_idx < 0) + return -ENOSPC; +@@ -331,10 +327,6 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + return ret; + + dev->mt76.vif_mask |= BIT_ULL(mlink->idx); +- if (!dev->mld_idx_mask) { +- dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); +- dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); +- } + dev->mld_idx_mask |= BIT_ULL(link->mld_idx); + phy->omac_mask |= BIT_ULL(mlink->omac_idx); + +@@ -424,11 +416,6 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, + dev->mt76.vif_mask &= ~BIT_ULL(mlink->idx); + dev->mld_idx_mask &= ~BIT_ULL(link->mld_idx); + phy->omac_mask &= ~BIT_ULL(mlink->omac_idx); +- if (!(dev->mld_idx_mask & ~BIT_ULL(mvif->mld_group_idx))) { +- /* last link */ +- dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); +- dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); +- } + + spin_lock_bh(&dev->mt76.sta_poll_lock); + if (!list_empty(&msta_link->wcid.poll_list)) +@@ -2217,7 +2204,42 @@ mt7996_change_vif_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u16 old_links, u16 new_links, + struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS]) + { +- return 0; ++ struct mt7996_dev *dev = mt7996_hw_dev(hw); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ int ret = 0; ++ ++ mutex_lock(&dev->mt76.mutex); ++ ++ if (!old_links) { ++ int idx; ++ ++ idx = get_own_mld_idx(dev->mld_idx_mask, true); ++ if (idx < 0) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ mvif->mld_group_idx = idx; ++ dev->mld_idx_mask |= BIT_ULL(mvif->mld_group_idx); ++ ++ idx = get_free_idx(dev->mld_remap_idx_mask, 0, 15) - 1; ++ if (idx < 0) { ++ ret = -ENOSPC; ++ goto out; ++ } ++ mvif->mld_remap_idx = idx; ++ dev->mld_remap_idx_mask |= BIT_ULL(mvif->mld_remap_idx); ++ } ++ ++ if (new_links) ++ goto out; ++ ++ dev->mld_idx_mask &= ~BIT_ULL(mvif->mld_group_idx); ++ dev->mld_remap_idx_mask &= ~BIT_ULL(mvif->mld_remap_idx); ++ ++out: ++ mutex_unlock(&dev->mt76.mutex); ++ ++ return ret; + } + + static void +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-mlo-set-key-and-group-key-issue.patch b/queue-6.18/wifi-mt76-mt7996-fix-mlo-set-key-and-group-key-issue.patch new file mode 100644 index 0000000000..509c8cdacb --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-mlo-set-key-and-group-key-issue.patch @@ -0,0 +1,191 @@ +From 7e77f7cd235c8398f11bd5a6d50f936669ad84fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:01 +0800 +Subject: wifi: mt76: mt7996: fix MLO set key and group key issues + +From: Shayne Chen + +[ Upstream commit e11be918d91e7d33ac4bad41dbe666a9abf1cfaa ] + +This patch fixes the following key issues: +- Pass correct link BSS to mt7996_mcu_add_key(), and use HW beacon + protection mode for mt7990 chipset +- Do not do group key deletion for GTK and IGTK due to FW design, the + delete key command will delete all group keys of a link BSS +- For deleting BIGTK, FW adds a new flow, but the "sec->add" field + should be filled with "SET_KEY". Note that if BIGTK is not deleted, it + will cause beacon decryption issue when switching from an AP interface + to a station interface + +Fixes: 0c45d52276fd ("wifi: mt76: mt7996: fix setting beacon protection keys") +Co-developed-by: Allen Ye +Signed-off-by: Allen Ye +Co-developed-by: Peter Chiu +Signed-off-by: Peter Chiu +Signed-off-by: Shayne Chen +Link: https://patch.msgid.link/20251106064203.1000505-10-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/mac.c | 7 +++- + .../net/wireless/mediatek/mt76/mt7996/main.c | 5 +-- + .../net/wireless/mediatek/mt76/mt7996/mcu.c | 35 +++++++++++++------ + .../wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- + 4 files changed, 34 insertions(+), 15 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 284f2eea71e5b..fe31db5440a84 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -794,6 +794,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, + u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; + __le16 fc = hdr->frame_control, sc = hdr->seq_ctrl; + u16 seqno = le16_to_cpu(sc); ++ bool hw_bigtk = false; + u8 fc_type, fc_stype; + u32 val; + +@@ -819,7 +820,11 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi, + info->flags & IEEE80211_TX_CTL_USE_MINRATE) + val |= MT_TXD1_FIXED_RATE; + +- if (key && multicast && ieee80211_is_robust_mgmt_frame(skb)) { ++ if (is_mt7990(&dev->mt76) && ieee80211_is_beacon(fc) && ++ (wcid->hw_key_idx2 == 6 || wcid->hw_key_idx2 == 7)) ++ hw_bigtk = true; ++ ++ if ((key && multicast && ieee80211_is_robust_mgmt_frame(skb)) || hw_bigtk) { + val |= MT_TXD1_BIP; + txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME); + } +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index dc0fcf5cb7fb1..beb455185f904 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -249,12 +249,13 @@ mt7996_set_hw_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, + else if (idx == *wcid_keyidx) + *wcid_keyidx = -1; + +- if (cmd != SET_KEY && sta) ++ /* only do remove key for BIGTK */ ++ if (cmd != SET_KEY && !is_bigtk) + return 0; + + mt76_wcid_key_setup(&dev->mt76, &msta_link->wcid, key); + +- err = mt7996_mcu_add_key(&dev->mt76, vif, key, ++ err = mt7996_mcu_add_key(&dev->mt76, link, key, + MCU_WMWA_UNI_CMD(STA_REC_UPDATE), + &msta_link->wcid, cmd); + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 21be88e76c655..5bde9959bbb99 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -2527,7 +2527,7 @@ int mt7996_mcu_teardown_mld_sta(struct mt7996_dev *dev, + } + + static int +-mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, ++mt7996_mcu_sta_key_tlv(struct mt76_dev *dev, struct mt76_wcid *wcid, + struct sk_buff *skb, + struct ieee80211_key_conf *key, + enum set_key_cmd cmd) +@@ -2539,7 +2539,10 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, + + tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec)); + sec = (struct sta_rec_sec_uni *)tlv; +- sec->add = 0; ++ /* due to connac3 FW design, we only do remove key for BIGTK; even for ++ * removal, the field should be filled with SET_KEY ++ */ ++ sec->add = SET_KEY; + sec->n_cipher = 1; + sec_key = &sec->key[0]; + sec_key->wlan_idx = cpu_to_le16(wcid->idx); +@@ -2579,29 +2582,33 @@ mt7996_mcu_sta_key_tlv(struct mt76_wcid *wcid, + case WLAN_CIPHER_SUITE_BIP_GMAC_256: + sec_key->cipher_id = MCU_CIPHER_BCN_PROT_GMAC_256; + break; ++ case WLAN_CIPHER_SUITE_BIP_CMAC_256: ++ if (!is_mt7990(dev)) ++ return -EOPNOTSUPP; ++ sec_key->cipher_id = MCU_CIPHER_BCN_PROT_CMAC_256; ++ break; + default: + return -EOPNOTSUPP; + } + +- sec_key->bcn_mode = BP_SW_MODE; ++ sec_key->bcn_mode = is_mt7990(dev) ? BP_HW_MODE : BP_SW_MODE; + + return 0; + } + +-int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, ++int mt7996_mcu_add_key(struct mt76_dev *dev, struct mt7996_vif_link *link, + struct ieee80211_key_conf *key, int mcu_cmd, + struct mt76_wcid *wcid, enum set_key_cmd cmd) + { +- struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv; + struct sk_buff *skb; + int ret; + +- skb = __mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid, +- MT7996_STA_UPDATE_MAX_SIZE); ++ skb = __mt76_connac_mcu_alloc_sta_req(dev, (struct mt76_vif_link *)link, ++ wcid, MT7996_STA_UPDATE_MAX_SIZE); + if (IS_ERR(skb)) + return PTR_ERR(skb); + +- ret = mt7996_mcu_sta_key_tlv(wcid, skb, key, cmd); ++ ret = mt7996_mcu_sta_key_tlv(dev, wcid, skb, key, cmd); + if (ret) { + dev_kfree_skb(skb); + return ret; +@@ -2721,12 +2728,18 @@ mt7996_mcu_beacon_mbss(struct sk_buff *rskb, struct sk_buff *skb, + static void + mt7996_mcu_beacon_cont(struct mt7996_dev *dev, + struct ieee80211_bss_conf *link_conf, ++ struct mt7996_vif_link *link, + struct sk_buff *rskb, struct sk_buff *skb, + struct bss_bcn_content_tlv *bcn, + struct ieee80211_mutable_offsets *offs) + { +- struct mt76_wcid *wcid = &dev->mt76.global_wcid; +- u8 *buf; ++ u8 *buf, keyidx = link->msta_link.wcid.hw_key_idx2; ++ struct mt76_wcid *wcid; ++ ++ if (is_mt7990(&dev->mt76) && (keyidx == 6 || keyidx == 7)) ++ wcid = &link->msta_link.wcid; ++ else ++ wcid = &dev->mt76.global_wcid; + + bcn->pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len); + bcn->tim_ie_pos = cpu_to_le16(offs->tim_offset); +@@ -2801,7 +2814,7 @@ int mt7996_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + info = IEEE80211_SKB_CB(skb); + info->hw_queue |= FIELD_PREP(MT_TX_HW_QUEUE_PHY, mlink->band_idx); + +- mt7996_mcu_beacon_cont(dev, link_conf, rskb, skb, bcn, &offs); ++ mt7996_mcu_beacon_cont(dev, link_conf, link, rskb, skb, bcn, &offs); + if (link_conf->bssid_indicator) + mt7996_mcu_beacon_mbss(rskb, skb, bcn, &offs); + mt7996_mcu_beacon_cntdwn(rskb, skb, &offs, link_conf->csa_active); +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +index 1727e73a99ce6..b942928c79e28 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +@@ -848,7 +848,7 @@ void mt7996_update_channel(struct mt76_phy *mphy); + int mt7996_init_debugfs(struct mt7996_dev *dev); + void mt7996_debugfs_rx_fw_monitor(struct mt7996_dev *dev, const void *data, int len); + bool mt7996_debugfs_rx_log(struct mt7996_dev *dev, const void *data, int len); +-int mt7996_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif, ++int mt7996_mcu_add_key(struct mt76_dev *dev, struct mt7996_vif_link *link, + struct ieee80211_key_conf *key, int mcu_cmd, + struct mt76_wcid *wcid, enum set_key_cmd cmd); + int mt7996_mcu_bcn_prot_enable(struct mt7996_dev *dev, +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch b/queue-6.18/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch new file mode 100644 index 0000000000..cf4314559a --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-null-pointer-deref-in-mt7996_co.patch @@ -0,0 +1,102 @@ +From 92684cc4499a97a2c749723074c7a9c102a7d9d0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 13:17:23 +0200 +Subject: wifi: mt76: mt7996: fix null pointer deref in mt7996_conf_tx() + +From: Felix Fietkau + +[ Upstream commit 79277f8ad15ec5f255ed0e1427c7a8a3e94e7f52 ] + +If a link does not have an assigned channel yet, mt7996_vif_link returns +NULL. We still need to store the updated queue settings in that case, and +apply them later. +Move the location of the queue params to within struct mt7996_vif_link. + +Fixes: c0df2f0caa8d ("wifi: mt76: mt7996: prepare mt7996_mcu_set_tx for MLO support") +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250929111723.52486-1-nbd@nbd.name +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 +++--- + drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 5 ++++- + drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h | 7 ++++++- + 3 files changed, 13 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 581314368c5ba..b53ca702591c6 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -665,8 +665,8 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + unsigned int link_id, u16 queue, + const struct ieee80211_tx_queue_params *params) + { +- struct mt7996_dev *dev = mt7996_hw_dev(hw); +- struct mt7996_vif_link *mlink = mt7996_vif_link(dev, vif, link_id); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; + static const u8 mq_to_aci[] = { + [IEEE80211_AC_VO] = 3, + [IEEE80211_AC_VI] = 2, +@@ -675,7 +675,7 @@ mt7996_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + }; + + /* firmware uses access class index */ +- mlink->queue_params[mq_to_aci[queue]] = *params; ++ link_info->queue_params[mq_to_aci[queue]] = *params; + /* no need to update right away, we'll get BSS_CHANGED_QOS */ + + return 0; +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 0347ee0c2dd75..afa6a43bd51e5 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -3414,6 +3414,9 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + #define WMM_PARAM_SET (WMM_AIFS_SET | WMM_CW_MIN_SET | \ + WMM_CW_MAX_SET | WMM_TXOP_SET) + struct mt7996_vif_link *link = mt7996_vif_conf_link(dev, vif, link_conf); ++ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; ++ unsigned int link_id = link_conf->link_id; ++ struct mt7996_vif_link_info *link_info = &mvif->link_info[link_id]; + struct { + u8 bss_idx; + u8 __rsv[3]; +@@ -3431,7 +3434,7 @@ int mt7996_mcu_set_tx(struct mt7996_dev *dev, struct ieee80211_vif *vif, + skb_put_data(skb, &hdr, sizeof(hdr)); + + for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { +- struct ieee80211_tx_queue_params *q = &link->queue_params[ac]; ++ struct ieee80211_tx_queue_params *q = &link_info->queue_params[ac]; + struct edca *e; + struct tlv *tlv; + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +index 8ec2acdb33193..718e4d4ad85f2 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +@@ -253,16 +253,21 @@ struct mt7996_vif_link { + struct mt7996_sta_link msta_link; + struct mt7996_phy *phy; + +- struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; + struct cfg80211_bitrate_mask bitrate_mask; + + u8 mld_idx; + }; + ++struct mt7996_vif_link_info { ++ struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS]; ++}; ++ + struct mt7996_vif { + struct mt7996_vif_link deflink; /* must be first */ + struct mt76_vif_data mt76; + ++ struct mt7996_vif_link_info link_info[IEEE80211_MLD_MAX_NUM_LINKS]; ++ + u8 mld_group_idx; + u8 mld_remap_idx; + }; +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch b/queue-6.18/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch new file mode 100644 index 0000000000..b51c4bd296 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-several-fields-in-mt7996_mcu_bs.patch @@ -0,0 +1,84 @@ +From 8f94302ffb85cb26e04b99978c9b9ada25352748 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:56 +0800 +Subject: wifi: mt76: mt7996: fix several fields in mt7996_mcu_bss_basic_tlv() + +From: Shayne Chen + +[ Upstream commit bb705a606734e1ce0ff17a4f368a896757ba686d ] + +Fix several fields in mt7996_mcu_bss_basic_tlv() that were not obtained +from the correct link. Without this patch, the MLD station interface +does not function properly. + +Fixes: 34a41bfbcb71 ("wifi: mt76: mt7996: prepare mt7996_mcu_add_dev/bss_info for MLO support") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-5-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + .../net/wireless/mediatek/mt76/mt7996/mcu.c | 21 ++++++++++--------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +index 9af3c48707ab7..21be88e76c655 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +@@ -1034,7 +1034,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + struct mt76_connac_bss_basic_tlv *bss; + u32 type = CONNECTION_INFRA_AP; + u16 sta_wlan_idx = wlan_idx; +- struct ieee80211_sta *sta; + struct tlv *tlv; + int idx; + +@@ -1045,14 +1044,18 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + break; + case NL80211_IFTYPE_STATION: + if (enable) { ++ struct ieee80211_sta *sta; ++ + rcu_read_lock(); +- sta = ieee80211_find_sta(vif, vif->bss_conf.bssid); +- /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */ ++ sta = ieee80211_find_sta(vif, link_conf->bssid); + if (sta) { +- struct mt76_wcid *wcid; ++ struct mt7996_sta *msta = (void *)sta->drv_priv; ++ struct mt7996_sta_link *msta_link; ++ int link_id = link_conf->link_id; + +- wcid = (struct mt76_wcid *)sta->drv_priv; +- sta_wlan_idx = wcid->idx; ++ msta_link = rcu_dereference(msta->link[link_id]); ++ if (msta_link) ++ sta_wlan_idx = msta_link->wcid.idx; + } + rcu_read_unlock(); + } +@@ -1069,8 +1072,6 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_BASIC, sizeof(*bss)); + + bss = (struct mt76_connac_bss_basic_tlv *)tlv; +- bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); +- bss->dtim_period = link_conf->dtim_period; + bss->bmc_tx_wlan_idx = cpu_to_le16(wlan_idx); + bss->sta_idx = cpu_to_le16(sta_wlan_idx); + bss->conn_type = cpu_to_le32(type); +@@ -1090,10 +1091,10 @@ mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, + + memcpy(bss->bssid, link_conf->bssid, ETH_ALEN); + bss->bcn_interval = cpu_to_le16(link_conf->beacon_int); +- bss->dtim_period = vif->bss_conf.dtim_period; ++ bss->dtim_period = link_conf->dtim_period; + bss->phymode = mt76_connac_get_phy_mode(phy, vif, + chandef->chan->band, NULL); +- bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, &vif->bss_conf, ++ bss->phymode_ext = mt76_connac_get_phy_mode_ext(phy, link_conf, + chandef->chan->band); + + return 0; +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch b/queue-6.18/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch new file mode 100644 index 0000000000..0f7cf80a02 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-teardown-command-for-an-mld-pee.patch @@ -0,0 +1,48 @@ +From 87bdb1c2abc67568d72a6a845107200b8692527d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:57 +0800 +Subject: wifi: mt76: mt7996: fix teardown command for an MLD peer + +From: Shayne Chen + +[ Upstream commit e077071e7ac48d5453072f615d51629891c5b90d ] + +For an MLD peer, we only need to call the teardown command when removing +the last link, and there's no need to call mt7996_mcu_add_sta() for the +earlier links. + +Fixes: c1d6dd5d03eb ("wifi: mt76: mt7996: Add mt7996_mcu_teardown_mld_sta rouine") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-6-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 2b52d057287a1..aa46ea707b406 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -1206,13 +1206,13 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + mt7996_mac_twt_teardown_flow(dev, link, + msta_link, i); + +- if (sta->mlo && links == BIT(link_id)) /* last link */ +- mt7996_mcu_teardown_mld_sta(dev, link, +- msta_link); +- else ++ if (!sta->mlo) + mt7996_mcu_add_sta(dev, link_conf, link_sta, + link, msta_link, + CONN_STATE_DISCONNECT, false); ++ else if (sta->mlo && links == BIT(link_id)) /* last link */ ++ mt7996_mcu_teardown_mld_sta(dev, link, ++ msta_link); + msta_link->wcid.sta_disabled = 1; + msta_link->wcid.sta = 0; + links = links & ~BIT(link_id); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch b/queue-6.18/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch new file mode 100644 index 0000000000..1ec9846483 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-fix-using-wrong-phy-to-start-in-mt7.patch @@ -0,0 +1,38 @@ +From 0969a1ff79f16a1116be635617948dc4bbbb67cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:42:02 +0800 +Subject: wifi: mt76: mt7996: fix using wrong phy to start in + mt7996_mac_restart() + +From: Shayne Chen + +[ Upstream commit f1e9f369ae42ee433836b24467e645192d046a51 ] + +Pass the correct mt7996_phy to mt7996_run(). + +Fixes: 0a5df0ec47f7 ("wifi: mt76: mt7996: remove redundant per-phy mac80211 calls during restart") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-11-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index fe31db5440a84..b06728a98a691 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -2341,7 +2341,7 @@ mt7996_mac_restart(struct mt7996_dev *dev) + if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) + continue; + +- ret = mt7996_run(&dev->phy); ++ ret = mt7996_run(phy); + if (ret) + goto out; + } +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch b/queue-6.18/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch new file mode 100644 index 0000000000..7c1ee98a7c --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-grab-mt76-mutex-in-mt7996_mac_sta_e.patch @@ -0,0 +1,82 @@ +From 4ed8771def99113b6633a07355bf8f0a5f9056a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:16:21 +0100 +Subject: wifi: mt76: mt7996: grab mt76 mutex in mt7996_mac_sta_event() + +From: Lorenzo Bianconi + +[ Upstream commit 5a4bcba26e9fbea87507a81ad891e70bb525014f ] + +Grab mt76 mutex in mt7996_mac_sta_event routine in order to rely on +mt76_dereference() utility macro. + +Fixes: ecd72f9695e7e ("wifi: mt76: mt7996: Support MLO in mt7996_mac_sta_event()") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251114-mt76-fix-missing-mtx-v1-1-259ebf11f654@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index beb455185f904..ead56ce4c0362 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -1150,12 +1150,15 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + unsigned long links = sta->valid_links; + struct ieee80211_link_sta *link_sta; + unsigned int link_id; ++ int err = 0; ++ ++ mutex_lock(&dev->mt76.mutex); + + for_each_sta_active_link(vif, sta, link_sta, link_id) { + struct ieee80211_bss_conf *link_conf; + struct mt7996_sta_link *msta_link; + struct mt7996_vif_link *link; +- int i, err; ++ int i; + + link_conf = link_conf_dereference_protected(vif, link_id); + if (!link_conf) +@@ -1175,12 +1178,12 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + link, msta_link, + CONN_STATE_CONNECT, true); + if (err) +- return err; ++ goto unlock; + + err = mt7996_mcu_add_rate_ctrl(dev, msta_link->sta, vif, + link_id, false); + if (err) +- return err; ++ goto unlock; + + msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; + break; +@@ -1189,7 +1192,7 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + link, msta_link, + CONN_STATE_PORT_SECURE, false); + if (err) +- return err; ++ goto unlock; + break; + case MT76_STA_EVENT_DISASSOC: + for (i = 0; i < ARRAY_SIZE(msta_link->twt.flow); i++) +@@ -1209,8 +1212,10 @@ mt7996_mac_sta_event(struct mt7996_dev *dev, struct ieee80211_vif *vif, + break; + } + } ++unlock: ++ mutex_unlock(&dev->mt76.mutex); + +- return 0; ++ return err; + } + + static void +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-remove-unnecessary-link_id-checks-i.patch b/queue-6.18/wifi-mt76-mt7996-remove-unnecessary-link_id-checks-i.patch new file mode 100644 index 0000000000..bd09fec50f --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-remove-unnecessary-link_id-checks-i.patch @@ -0,0 +1,63 @@ +From 93f446aba0f9bddfa4b20095fc34377805d9f330 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 15:51:39 +0200 +Subject: wifi: mt76: mt7996: Remove unnecessary link_id checks in mt7996_tx + +From: Lorenzo Bianconi + +[ Upstream commit 084922069ceac4d594c06b76a80352139fd15f4d ] + +Remove unnecessary link_id checks in mt7996_tx routine since if the link +identifier provided by mac80211 is unspecified the value will be +overwritten at the beginning on the function. + +Fixes: f940c9b7aef6 ("wifi: mt76: mt7996: Set proper link destination address in mt7996_tx()") +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20250924-mt76_tx_unnecessary-check-v1-1-e595930a5662@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index b53ca702591c6..2b52d057287a1 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -1339,12 +1339,10 @@ static void mt7996_tx(struct ieee80211_hw *hw, + } + + if (mvif) { +- struct mt76_vif_link *mlink = &mvif->deflink.mt76; ++ struct mt76_vif_link *mlink; + +- if (link_id < IEEE80211_LINK_UNSPECIFIED) +- mlink = rcu_dereference(mvif->mt76.link[link_id]); +- +- if (mlink->wcid) ++ mlink = rcu_dereference(mvif->mt76.link[link_id]); ++ if (mlink && mlink->wcid) + wcid = mlink->wcid; + + if (mvif->mt76.roc_phy && +@@ -1352,7 +1350,7 @@ static void mt7996_tx(struct ieee80211_hw *hw, + mphy = mvif->mt76.roc_phy; + if (mphy->roc_link) + wcid = mphy->roc_link->wcid; +- } else { ++ } else if (mlink) { + mphy = mt76_vif_link_phy(mlink); + } + } +@@ -1362,7 +1360,7 @@ static void mt7996_tx(struct ieee80211_hw *hw, + goto unlock; + } + +- if (msta && link_id < IEEE80211_LINK_UNSPECIFIED) { ++ if (msta) { + struct mt7996_sta_link *msta_link; + + msta_link = rcu_dereference(msta->link[link_id]); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-remove-useless-check-in-mt7996_msdu.patch b/queue-6.18/wifi-mt76-mt7996-remove-useless-check-in-mt7996_msdu.patch new file mode 100644 index 0000000000..761b170681 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-remove-useless-check-in-mt7996_msdu.patch @@ -0,0 +1,41 @@ +From c6f9446ba0bd23ea68211e193a539b5296f3402a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 14 Oct 2025 15:28:53 +0200 +Subject: wifi: mt76: mt7996: Remove useless check in + mt7996_msdu_page_get_from_cache() + +From: Lorenzo Bianconi + +[ Upstream commit 2157e49892c5eae210b8fa6ee8672bd9d0ffa4b5 ] + +Get rid of useless null-pointer check in mt7996_msdu_page_get_from_cache +since we have already verfied the list is not empty. + +Fixes: b1e58e137b616 ("wifi: mt76: mt7996: Introduce RRO MSDU callbacks") +Reported-by: kernel test robot +Closes: https://lore.kernel.org/r/202510100155.MS0IXhzm-lkp@intel.com/ +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251014-mt7996_msdu_page_get_from_cache-remove-null-ptr-check-v1-1-fbeb7881e192@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +index 9501def3e0e3e..284f2eea71e5b 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c +@@ -1681,8 +1681,7 @@ mt7996_msdu_page_get_from_cache(struct mt7996_dev *dev) + if (!list_empty(&dev->wed_rro.page_cache)) { + p = list_first_entry(&dev->wed_rro.page_cache, + struct mt7996_msdu_page, list); +- if (p) +- list_del(&p->list); ++ list_del(&p->list); + } + + spin_unlock(&dev->wed_rro.lock); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch b/queue-6.18/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch new file mode 100644 index 0000000000..b29e3b9be3 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-set-link_valid-field-when-initializ.patch @@ -0,0 +1,45 @@ +From aebc4e5c7b1d75f9159a302256443292c6ada471 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:41:58 +0800 +Subject: wifi: mt76: mt7996: set link_valid field when initializing wcid + +From: Shayne Chen + +[ Upstream commit 7eaea3a8ba1e9bb58f87e3030f6ce18537e57e1f ] + +This ensures the upper layer uses the correct link ID during packet +processing. + +Fixes: dd82a9e02c05 ("wifi: mt76: mt7996: Rely on mt7996_sta_link in sta_add/sta_remove callbacks") +Signed-off-by: Shayne Chen +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251106064203.1000505-7-shayne.chen@mediatek.com +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index aa46ea707b406..4e73854589558 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -343,6 +343,7 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + INIT_LIST_HEAD(&msta_link->rc_list); + msta_link->wcid.idx = idx; + msta_link->wcid.link_id = link_conf->link_id; ++ msta_link->wcid.link_valid = ieee80211_vif_is_mld(vif); + msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET; + mt76_wcid_init(&msta_link->wcid, band_idx); + +@@ -984,6 +985,7 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev, + msta_link->wcid.sta = 1; + msta_link->wcid.idx = idx; + msta_link->wcid.link_id = link_id; ++ msta_link->wcid.link_valid = !!sta->valid_links; + msta_link->wcid.def_wcid = &msta->deflink.wcid; + + ewma_avg_signal_init(&msta_link->avg_ack_signal); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch b/queue-6.18/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch new file mode 100644 index 0000000000..066f793853 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-skip-deflink-accounting-for-offchan.patch @@ -0,0 +1,48 @@ +From a002dd005c2f38ff51d7f78ebf4a9eda234e3e5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 14:16:24 +0100 +Subject: wifi: mt76: mt7996: skip deflink accounting for offchannel links + +From: Lorenzo Bianconi + +[ Upstream commit 4fe823b9ee0317b04ddc6d9e00fea892498aa0f2 ] + +Do not take into account offchannel links for deflink accounting. + +Fixes: a3316d2fc669f ("wifi: mt76: mt7996: set vif default link_id adding/removing vif links") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251114-mt76-fix-missing-mtx-v1-4-259ebf11f654@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index ead56ce4c0362..5ff7ab596f88c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -370,7 +370,8 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif, + + ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); + +- if (mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) ++ if (!mlink->wcid->offchannel && ++ mvif->mt76.deflink_id == IEEE80211_LINK_UNSPECIFIED) + mvif->mt76.deflink_id = link_conf->link_id; + + return 0; +@@ -401,7 +402,8 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, + + rcu_assign_pointer(dev->mt76.wcid[idx], NULL); + +- if (mvif->mt76.deflink_id == link_conf->link_id) { ++ if (!mlink->wcid->offchannel && ++ mvif->mt76.deflink_id == link_conf->link_id) { + struct ieee80211_bss_conf *iter; + unsigned int link_id; + +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-mt7996-skip-ieee80211_iter_keys-on-scannin.patch b/queue-6.18/wifi-mt76-mt7996-skip-ieee80211_iter_keys-on-scannin.patch new file mode 100644 index 0000000000..ed1de36b13 --- /dev/null +++ b/queue-6.18/wifi-mt76-mt7996-skip-ieee80211_iter_keys-on-scannin.patch @@ -0,0 +1,85 @@ +From 2d900b7c2bc1cde8893d0d13227c41fe1f8a8f99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 11:41:00 +0100 +Subject: wifi: mt76: mt7996: skip ieee80211_iter_keys() on scanning link + remove + +From: Lorenzo Bianconi + +[ Upstream commit 2a432a6d0066d4ce05a2d0eec1da9e061eb70c49 ] + +mt7996_vif_link_remove routine is executed by mt76_scan_complete() +without holding the wiphy mutex triggering the following lockdep warning. + + WARNING: CPU: 0 PID: 72 at net/mac80211/key.c:1029 ieee80211_iter_keys+0xe4/0x1a0 [mac80211] + CPU: 0 UID: 0 PID: 72 Comm: kworker/u32:2 Tainted: G S 6.18.0-rc5+ #27 PREEMPT(full) + Tainted: [S]=CPU_OUT_OF_SPEC + Hardware name: Default string Default string/SKYBAY, BIOS 5.12 02/15/2023 + Workqueue: phy3 mt76_scan_work [mt76] + RIP: 0010:ieee80211_iter_keys+0xe4/0x1a0 [mac80211] + Code: 4c 48 83 c4 10 5b 5d 41 5c 41 5d 41 5e 41 5f c3 48 8b 47 48 be ff ff ff ff 48 8d 78 68 e8 b4 eb 1e e1 85 c0 0f 85 49 +ff ff ff 4c 8b ab 90 1a 00 00 48 8d 83 90 + RSP: 0018:ffffc900002f7cb0 EFLAGS: 00010246 + RAX: 0000000000000000 RBX: ffff888127e00ee0 RCX: 0000000000000000 + RDX: 0000000000000000 RSI: ffff888127e00788 RDI: ffff88811132b5c8 + RBP: ffffffffa0ddf400 R08: 0000000000000001 R09: 000000009dcc1dac + R10: 0000000000000001 R11: ffff88811132b5a0 R12: ffffc900002f7d00 + R13: ffff8882581e6a80 R14: ffff888127e0afc8 R15: ffff888158832038 + FS: 0000000000000000(0000) GS:ffff8884da486000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000030a0fd90 CR3: 0000000002c52004 CR4: 00000000003706f0 + Call Trace: + + ? lock_acquire+0xc2/0x2c0 + mt7996_vif_link_remove+0x64/0x2b0 [mt7996e] + mt76_put_vif_phy_link+0x41/0x50 [mt76] + mt76_scan_complete+0x77/0x100 [mt76] + mt76_scan_work+0x2eb/0x3f0 [mt76] + ? process_one_work+0x1e5/0x6d0 + process_one_work+0x221/0x6d0 + worker_thread+0x19a/0x340 + ? rescuer_thread+0x450/0x450 + kthread+0x108/0x220 + ? kthreads_online_cpu+0x110/0x110 + ret_from_fork+0x1c6/0x220 + ? kthreads_online_cpu+0x110/0x110 + ret_from_fork_asm+0x11/0x20 + + irq event stamp: 45471 + hardirqs last enabled at (45477): [] __up_console_sem+0x5e/0x70 + hardirqs last disabled at (45482): [] __up_console_sem+0x43/0x70 + softirqs last enabled at (44500): [] napi_pp_put_page+0xac/0xd0 + softirqs last disabled at (44498): [] page_pool_put_unrefed_netmem+0x290/0x3d0 + ---[ end trace 0000000000000000 ]--- + +Fix the issue skipping ieee80211_iter_keys() for scanning links in +mt7996_vif_link_remove routine since we have not uploaded any hw keys +for these links. + +Fixes: 04414d7bba78 ("wifi: mt76: mt7996: delete vif keys when requested") +Signed-off-by: Lorenzo Bianconi +Tested-by: Ben Greear +Link: https://patch.msgid.link/20251115-mt7996-key-iter-link-remove-fix-v1-1-4f3f4e1eaa78@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7996/main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +index 5ff7ab596f88c..2ad52ae2c5f55 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c +@@ -392,7 +392,8 @@ void mt7996_vif_link_remove(struct mt76_phy *mphy, struct ieee80211_vif *vif, + }; + int idx = msta_link->wcid.idx; + +- ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); ++ if (!mlink->wcid->offchannel) ++ ieee80211_iter_keys(mphy->hw, vif, mt7996_key_iter, &it); + + mt7996_mcu_add_sta(dev, link_conf, NULL, link, NULL, + CONN_STATE_DISCONNECT, false); +-- +2.51.0 + diff --git a/queue-6.18/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch b/queue-6.18/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch new file mode 100644 index 0000000000..7014b66392 --- /dev/null +++ b/queue-6.18/wifi-mt76-wed-use-proper-wed-reference-in-mt76-wed-d.patch @@ -0,0 +1,175 @@ +From 72b228878d9bc4623051e6c6931060dc769b8762 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 12:41:48 +0200 +Subject: wifi: mt76: wed: use proper wed reference in mt76 wed driver + callabacks + +From: Lorenzo Bianconi + +[ Upstream commit 385aab8fccd7a8746b9f1a17f3c1e38498a14bc7 ] + +MT7996 driver can use both wed and wed_hif2 devices to offload traffic +from/to the wireless NIC. In the current codebase we assume to always +use the primary wed device in wed callbacks resulting in the following +crash if the hw runs wed_hif2 (e.g. 6GHz link). + +[ 297.455876] Unable to handle kernel read from unreadable memory at virtual address 000000000000080a +[ 297.464928] Mem abort info: +[ 297.467722] ESR = 0x0000000096000005 +[ 297.471461] EC = 0x25: DABT (current EL), IL = 32 bits +[ 297.476766] SET = 0, FnV = 0 +[ 297.479809] EA = 0, S1PTW = 0 +[ 297.482940] FSC = 0x05: level 1 translation fault +[ 297.487809] Data abort info: +[ 297.490679] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 +[ 297.496156] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 297.501196] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 297.506500] user pgtable: 4k pages, 39-bit VAs, pgdp=0000000107480000 +[ 297.512927] [000000000000080a] pgd=08000001097fb003, p4d=08000001097fb003, pud=08000001097fb003, pmd=0000000000000000 +[ 297.523532] Internal error: Oops: 0000000096000005 [#1] SMP +[ 297.715393] CPU: 2 UID: 0 PID: 45 Comm: kworker/u16:2 Tainted: G O 6.12.50 #0 +[ 297.723908] Tainted: [O]=OOT_MODULE +[ 297.727384] Hardware name: Banana Pi BPI-R4 (2x SFP+) (DT) +[ 297.732857] Workqueue: nf_ft_offload_del nf_flow_rule_route_ipv6 [nf_flow_table] +[ 297.740254] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) +[ 297.747205] pc : mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.752688] lr : mtk_wed_flow_remove+0x58/0x80 +[ 297.757126] sp : ffffffc080fe3ae0 +[ 297.760430] x29: ffffffc080fe3ae0 x28: ffffffc080fe3be0 x27: 00000000deadbef7 +[ 297.767557] x26: ffffff80c5ebca00 x25: 0000000000000001 x24: ffffff80c85f4c00 +[ 297.774683] x23: ffffff80c1875b78 x22: ffffffc080d42cd0 x21: ffffffc080660018 +[ 297.781809] x20: ffffff80c6a076d0 x19: ffffff80c6a043c8 x18: 0000000000000000 +[ 297.788935] x17: 0000000000000000 x16: 0000000000000001 x15: 0000000000000000 +[ 297.796060] x14: 0000000000000019 x13: ffffff80c0ad8ec0 x12: 00000000fa83b2da +[ 297.803185] x11: ffffff80c02700c0 x10: ffffff80c0ad8ec0 x9 : ffffff81fef96200 +[ 297.810311] x8 : ffffff80c02700c0 x7 : ffffff80c02700d0 x6 : 0000000000000002 +[ 297.817435] x5 : 0000000000000400 x4 : 0000000000000000 x3 : 0000000000000000 +[ 297.824561] x2 : 0000000000000001 x1 : 0000000000000800 x0 : ffffff80c6a063c8 +[ 297.831686] Call trace: +[ 297.834123] mt76_wed_offload_disable+0x64/0xa0 [mt76] +[ 297.839254] mtk_wed_flow_remove+0x58/0x80 +[ 297.843342] mtk_flow_offload_cmd+0x434/0x574 +[ 297.847689] mtk_wed_setup_tc_block_cb+0x30/0x40 +[ 297.852295] nf_flow_offload_ipv6_hook+0x7f4/0x964 [nf_flow_table] +[ 297.858466] nf_flow_rule_route_ipv6+0x438/0x4a4 [nf_flow_table] +[ 297.864463] process_one_work+0x174/0x300 +[ 297.868465] worker_thread+0x278/0x430 +[ 297.872204] kthread+0xd8/0xdc +[ 297.875251] ret_from_fork+0x10/0x20 +[ 297.878820] Code: 928b5ae0 8b000273 91400a60 f943fa61 (79401421) +[ 297.884901] ---[ end trace 0000000000000000 ]--- + +Fix the issue detecting the proper wed reference to use running wed +callabacks. + +Fixes: 83eafc9251d6 ("wifi: mt76: mt7996: add wed tx support") +Tested-by: Daniel Pawlik +Tested-by: Matteo Croce +Signed-off-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251008-wed-fixes-v1-1-8f7678583385@kernel.org +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt76.h | 9 +++++++++ + drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 1 + + drivers/net/wireless/mediatek/mt76/wed.c | 10 +++++----- + include/linux/soc/mediatek/mtk_wed.h | 1 + + 4 files changed, 16 insertions(+), 5 deletions(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h +index e0d50b58cd012..7753afa3d883d 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt76.h ++++ b/drivers/net/wireless/mediatek/mt76/mt76.h +@@ -1252,6 +1252,15 @@ static inline int mt76_wed_dma_setup(struct mt76_dev *dev, struct mt76_queue *q, + #define mt76_dereference(p, dev) \ + rcu_dereference_protected(p, lockdep_is_held(&(dev)->mutex)) + ++static inline struct mt76_dev *mt76_wed_to_dev(struct mtk_wed_device *wed) ++{ ++#ifdef CONFIG_NET_MEDIATEK_SOC_WED ++ if (wed->wlan.hif2) ++ return container_of(wed, struct mt76_dev, mmio.wed_hif2); ++#endif /* CONFIG_NET_MEDIATEK_SOC_WED */ ++ return container_of(wed, struct mt76_dev, mmio.wed); ++} ++ + static inline struct mt76_wcid * + __mt76_wcid_ptr(struct mt76_dev *dev, u16 idx) + { +diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +index d14b626ee5115..80db102ed809c 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c +@@ -595,6 +595,7 @@ int mt7996_mmio_wed_init(struct mt7996_dev *dev, void *pdev_ptr, + + wed->wlan.nbuf = MT7996_HW_TOKEN_SIZE; + wed->wlan.token_start = MT7996_TOKEN_SIZE - wed->wlan.nbuf; ++ wed->wlan.hif2 = hif2; + + wed->wlan.amsdu_max_subframes = 8; + wed->wlan.amsdu_max_len = 1536; +diff --git a/drivers/net/wireless/mediatek/mt76/wed.c b/drivers/net/wireless/mediatek/mt76/wed.c +index 907a8e43e72ad..fbd7e59c73aaf 100644 +--- a/drivers/net/wireless/mediatek/mt76/wed.c ++++ b/drivers/net/wireless/mediatek/mt76/wed.c +@@ -8,7 +8,7 @@ + + void mt76_wed_release_rx_buf(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + int i; + + for (i = 0; i < dev->rx_token_size; i++) { +@@ -31,8 +31,8 @@ EXPORT_SYMBOL_GPL(mt76_wed_release_rx_buf); + #ifdef CONFIG_NET_MEDIATEK_SOC_WED + u32 mt76_wed_init_rx_buf(struct mtk_wed_device *wed, int size) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); + struct mtk_wed_bm_desc *desc = wed->rx_buf_ring.desc; ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + struct mt76_queue *q = &dev->q_rx[MT_RXQ_MAIN]; + struct mt76_txwi_cache *t = NULL; + int i; +@@ -80,7 +80,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_init_rx_buf); + + int mt76_wed_offload_enable(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + spin_lock_bh(&dev->token_lock); + dev->token_size = wed->wlan.token_start; +@@ -164,7 +164,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_dma_setup); + + void mt76_wed_offload_disable(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + spin_lock_bh(&dev->token_lock); + dev->token_size = dev->drv->token_size; +@@ -174,7 +174,7 @@ EXPORT_SYMBOL_GPL(mt76_wed_offload_disable); + + void mt76_wed_reset_complete(struct mtk_wed_device *wed) + { +- struct mt76_dev *dev = container_of(wed, struct mt76_dev, mmio.wed); ++ struct mt76_dev *dev = mt76_wed_to_dev(wed); + + complete(&dev->mmio.wed_reset_complete); + } +diff --git a/include/linux/soc/mediatek/mtk_wed.h b/include/linux/soc/mediatek/mtk_wed.h +index c4ff6bab176db..3fa93bd650044 100644 +--- a/include/linux/soc/mediatek/mtk_wed.h ++++ b/include/linux/soc/mediatek/mtk_wed.h +@@ -154,6 +154,7 @@ struct mtk_wed_device { + bool wcid_512; + bool hw_rro; + bool msi; ++ bool hif2; + + u16 token_start; + unsigned int nbuf; +-- +2.51.0 + diff --git a/queue-6.18/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-6.18/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..a1447c5f65 --- /dev/null +++ b/queue-6.18/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 8fd02758ee9bed5fc4efab3c0f3fc6f3ede80f5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index 2905baea62390..070c0431c4821 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-6.18/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-6.18/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..607645bce9 --- /dev/null +++ b/queue-6.18/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From 12bd03c554ae75d62f5a59dea8c72182782a3b3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index 0c5c66401daa6..7aa2da0cd63cc 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-6.18/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch b/queue-6.18/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch new file mode 100644 index 0000000000..e8c9b8fb2e --- /dev/null +++ b/queue-6.18/wifi-rtw89-usb-fix-leak-in-rtw89_usb_write_port.patch @@ -0,0 +1,54 @@ +From 871c3c46da06f8998da9c8197682c005e866014a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 16:57:09 +0300 +Subject: wifi: rtw89: usb: fix leak in rtw89_usb_write_port() + +From: Fedor Pchelkin + +[ Upstream commit 7543818e97d5d54b3b2f75f1c4dedee298d7d914 ] + +When there is an attempt to write data and RTW89_FLAG_UNPLUGGED is set, +this means device is disconnected and no urb is submitted. Return +appropriate error code to the caller to properly free the allocated +resources. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") +Acked-by: Ping-Ke Shih +Signed-off-by: Fedor Pchelkin +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251104135720.321110-3-pchelkin@ispras.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/usb.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c +index e8e064cf7e0ad..512a46dd9d06a 100644 +--- a/drivers/net/wireless/realtek/rtw89/usb.c ++++ b/drivers/net/wireless/realtek/rtw89/usb.c +@@ -256,7 +256,7 @@ static int rtw89_usb_write_port(struct rtw89_dev *rtwdev, u8 ch_dma, + int ret; + + if (test_bit(RTW89_FLAG_UNPLUGGED, rtwdev->flags)) +- return 0; ++ return -ENODEV; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) +@@ -305,8 +305,9 @@ static void rtw89_usb_ops_tx_kick_off(struct rtw89_dev *rtwdev, u8 txch) + ret = rtw89_usb_write_port(rtwdev, txch, skb->data, skb->len, + txcb); + if (ret) { +- rtw89_err(rtwdev, "write port txch %d failed: %d\n", +- txch, ret); ++ if (ret != -ENODEV) ++ rtw89_err(rtwdev, "write port txch %d failed: %d\n", ++ txch, ret); + + skb_dequeue(&txcb->tx_ack_queue); + kfree(txcb); +-- +2.51.0 + diff --git a/queue-6.18/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch b/queue-6.18/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch new file mode 100644 index 0000000000..ff3a2e3c1c --- /dev/null +++ b/queue-6.18/wifi-rtw89-usb-use-common-error-path-for-skbs-in-rtw.patch @@ -0,0 +1,59 @@ +From 82461fb76d332cc892684a1c850bfd9decc1839d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 16:57:08 +0300 +Subject: wifi: rtw89: usb: use common error path for skbs in + rtw89_usb_rx_handler() + +From: Fedor Pchelkin + +[ Upstream commit 28a45575289f3292aa9cb7bacae18ba3ee7a6adf ] + +Allow adding rx_skb to rx_free_queue for later reuse on the common error +handling path, otherwise free it. + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: 2135c28be6a8 ("wifi: rtw89: Add usb.{c,h}") +Acked-by: Ping-Ke Shih +Signed-off-by: Fedor Pchelkin +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251104135720.321110-2-pchelkin@ispras.ru +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtw89/usb.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtw89/usb.c b/drivers/net/wireless/realtek/rtw89/usb.c +index 6cf89aee252ed..e8e064cf7e0ad 100644 +--- a/drivers/net/wireless/realtek/rtw89/usb.c ++++ b/drivers/net/wireless/realtek/rtw89/usb.c +@@ -410,8 +410,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + + if (skb_queue_len(&rtwusb->rx_queue) >= RTW89_USB_MAX_RXQ_LEN) { + rtw89_warn(rtwdev, "rx_queue overflow\n"); +- dev_kfree_skb_any(rx_skb); +- continue; ++ goto free_or_reuse; + } + + memset(&desc_info, 0, sizeof(desc_info)); +@@ -422,7 +421,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + rtw89_debug(rtwdev, RTW89_DBG_HCI, + "failed to allocate RX skb of size %u\n", + desc_info.pkt_size); +- continue; ++ goto free_or_reuse; + } + + pkt_offset = desc_info.offset + desc_info.rxd_len; +@@ -432,6 +431,7 @@ static void rtw89_usb_rx_handler(struct work_struct *work) + + rtw89_core_rx(rtwdev, &desc_info, skb); + ++free_or_reuse: + if (skb_queue_len(&rtwusb->rx_free_queue) >= RTW89_USB_RX_SKB_NUM) + dev_kfree_skb_any(rx_skb); + else +-- +2.51.0 + diff --git a/queue-6.18/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch b/queue-6.18/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch new file mode 100644 index 0000000000..e4f72c18b6 --- /dev/null +++ b/queue-6.18/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch @@ -0,0 +1,87 @@ +From 54b5f0c7c205273e201f310af3be9c5f40267fd9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:22 +0000 +Subject: x86/boot: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit eb2266312507d7b757859e2227aa5c4ba6280ebe ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags. Bits above the + physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The PGD entry is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Acked-by: Dave Hansen +Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index bdd26050dff77..0e89e197e1126 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include "../string.h" + #include "efi.h" +@@ -168,9 +169,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * For 4- to 5-level paging transition, set up current CR3 as + * the first and the only entry in a new top-level page table. + */ +- *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; ++ *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; + } else { +- unsigned long src; ++ u64 *new_cr3; ++ pgd_t *pgdp; + + /* + * For 5- to 4-level paging transition, copy page table pointed +@@ -180,8 +182,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * We cannot just point to the page table from trampoline as it + * may be above 4G. + */ +- src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; +- memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); ++ pgdp = (pgd_t *)native_read_cr3_pa(); ++ new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); ++ memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); + } + + toggle_la57(trampoline_32bit); +-- +2.51.0 + diff --git a/queue-6.18/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-6.18/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..2135ec3afd --- /dev/null +++ b/queue-6.18/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From 72b4329340655e250ee5ea9c4b078f228c662a2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 71ee20102a8af..b10684dedc589 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -181,8 +181,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -303,6 +303,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 + diff --git a/queue-6.6/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch b/queue-6.6/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch new file mode 100644 index 0000000000..f555d98f36 --- /dev/null +++ b/queue-6.6/9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch @@ -0,0 +1,60 @@ +From 55b3ee65fbb23e36b39afac49a9f6e9d85648b14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 16:30:53 -0600 +Subject: 9p: fix cache/debug options printing in v9fs_show_options + +From: Eric Sandeen + +[ Upstream commit f0445613314f474c1a0ec6fa8a5cd153a618f1b6 ] + +commit 4eb3117888a92 changed the cache= option to accept either string +shortcuts or bitfield values. It also changed /proc/mounts to emit the +option as the hexadecimal numeric value rather than the shortcut string. + +However, by printing "cache=%x" without the leading 0x, shortcuts such +as "cache=loose" will emit "cache=f" and 'f' is not a string that is +parseable by kstrtoint(), so remounting may fail if a remount with +"cache=f" is attempted. + +debug=%x has had the same problem since options have been displayed in +c4fac9100456 ("9p: Implement show_options") + +Fix these by adding the 0x prefix to the hexadecimal value shown in +/proc/mounts. + +Fixes: 4eb3117888a92 ("fs/9p: Rework cache modes and add new options to Documentation") +Signed-off-by: Eric Sandeen +Message-ID: <54b93378-dcf1-4b04-922d-c8b4393da299@redhat.com> +[Dominique: use %#x at Al Viro's suggestion, also handle debug] +Tested-by: Remi Pommarel +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/v9fs.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c +index be61810cb7798..159a2aae849b9 100644 +--- a/fs/9p/v9fs.c ++++ b/fs/9p/v9fs.c +@@ -101,7 +101,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + struct v9fs_session_info *v9ses = root->d_sb->s_fs_info; + + if (v9ses->debug) +- seq_printf(m, ",debug=%x", v9ses->debug); ++ seq_printf(m, ",debug=%#x", v9ses->debug); + if (!uid_eq(v9ses->dfltuid, V9FS_DEFUID)) + seq_printf(m, ",dfltuid=%u", + from_kuid_munged(&init_user_ns, v9ses->dfltuid)); +@@ -117,7 +117,7 @@ int v9fs_show_options(struct seq_file *m, struct dentry *root) + if (v9ses->nodev) + seq_puts(m, ",nodevmap"); + if (v9ses->cache) +- seq_printf(m, ",cache=%x", v9ses->cache); ++ seq_printf(m, ",cache=%#x", v9ses->cache); + #ifdef CONFIG_9P_FSCACHE + if (v9ses->cachetag && (v9ses->cache & CACHE_FSCACHE)) + seq_printf(m, ",cachetag=%s", v9ses->cachetag); +-- +2.51.0 + diff --git a/queue-6.6/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch b/queue-6.6/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch new file mode 100644 index 0000000000..0a6e7261d1 --- /dev/null +++ b/queue-6.6/acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch @@ -0,0 +1,64 @@ +From 0f5030c31dac826ce95c8cedd132682b744736e1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 16:55:13 +0100 +Subject: ACPI: processor_core: fix map_x2apic_id for amd-pstate on am4 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: René Rebe + +[ Upstream commit 17e7972979e147cc51d4a165e6b6b0f93273ca68 ] + +On all AMD AM4 systems I have seen, e.g ASUS X470-i, Pro WS X570 Ace +and equivalent Gigabyte, amd-pstate does not initialize when the +x2apic is enabled in the BIOS. Kernel debug messages include: + +[ 0.315438] acpi LNXCPU:00: Failed to get CPU physical ID. +[ 0.354756] ACPI CPPC: No CPC descriptor for CPU:0 +[ 0.714951] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled + +I tracked this down to map_x2apic_id() checking device_declaration +passed in via the type argument of acpi_get_phys_id() via +map_madt_entry() while map_lapic_id() does not. + +It appears these BIOSes use Processor statements for declaring the CPUs +in the ACPI namespace instead of processor device objects (which should +have been used). CPU declarations via Processor statements were +deprecated in ACPI 6.0 that was released 10 years ago. They should not +be used any more in any contemporary platform firmware. + +I tried to contact Asus support multiple times, but never received a +reply nor did any BIOS update ever change this. + +Fix amd-pstate w/ x2apic on am4 by allowing map_x2apic_id() to work with +CPUs declared via Processor statements for IDs less than 255, which is +consistent with ACPI 5.0 that still allowed Processor statements to be +used for declaring CPUs. + +Fixes: 7237d3de78ff ("x86, ACPI: add support for x2apic ACPI extensions") +Signed-off-by: René Rebe +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251126.165513.1373131139292726554.rene@exactco.de +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/processor_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c +index 7dd6dbaa98c34..dea60d694343f 100644 +--- a/drivers/acpi/processor_core.c ++++ b/drivers/acpi/processor_core.c +@@ -54,7 +54,7 @@ static int map_x2apic_id(struct acpi_subtable_header *entry, + if (!(apic->lapic_flags & ACPI_MADT_ENABLED)) + return -ENODEV; + +- if (device_declaration && (apic->uid == acpi_id)) { ++ if (apic->uid == acpi_id && (device_declaration || acpi_id < 255)) { + *apic_id = apic->local_apic_id; + return 0; + } +-- +2.51.0 + diff --git a/queue-6.6/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch b/queue-6.6/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch new file mode 100644 index 0000000000..8e0f3cc1bf --- /dev/null +++ b/queue-6.6/acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch @@ -0,0 +1,44 @@ +From 6ec1467508da579b644c3d5d7c02745f520ec1f1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 15:50:00 +0800 +Subject: ACPI: property: Fix fwnode refcount leak in + acpi_fwnode_graph_parse_endpoint() + +From: Haotian Zhang + +[ Upstream commit 593ee49222a0d751062fd9a5e4a963ade4ec028a ] + +acpi_fwnode_graph_parse_endpoint() calls fwnode_get_parent() to obtain the +parent fwnode but returns without calling fwnode_handle_put() on it. This +potentially leads to a fwnode refcount leak and prevents the parent node +from being released properly. + +Call fwnode_handle_put() on the parent fwnode before returning to prevent +the leak from occurring. + +Fixes: 3b27d00e7b6d ("device property: Move fwnode graph ops to firmware specific locations") +Signed-off-by: Haotian Zhang +Reviewed-by: Sakari Ailus +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20251111075000.1828-1-vulab@iscas.ac.cn +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/property.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c +index d02b332744e64..1b8f3958b0edb 100644 +--- a/drivers/acpi/property.c ++++ b/drivers/acpi/property.c +@@ -1622,6 +1622,7 @@ static int acpi_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode, + if (fwnode_property_read_u32(fwnode, "reg", &endpoint->id)) + fwnode_property_read_u32(fwnode, "endpoint", &endpoint->id); + ++ fwnode_handle_put(port_fwnode); + return 0; + } + +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch b/queue-6.6/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch new file mode 100644 index 0000000000..f6d0eae289 --- /dev/null +++ b/queue-6.6/arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch @@ -0,0 +1,41 @@ +From 24881eeb510b9417d5f6d1fce9f7e345d8866b6c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:38:51 +0200 +Subject: ARM: dts: am335x-netcom-plus-2xx: add missing GPIO labels + +From: Yegor Yefremov + +[ Upstream commit d0c4b1723c419a18cb434903c7754954ecb51d35 ] + +Fixes: 8e9d75fd2ec2 ("ARM: dts: am335x-netcom: add GPIO names for NetCom Plus 2-port devices") + +Signed-off-by: Yegor Yefremov +Link: https://lore.kernel.org/r/20251007103851.3765678-1-yegorslists@googlemail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +index 76751a324ad75..441d4696b94d9 100644 +--- a/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts ++++ b/arch/arm/boot/dts/ti/omap/am335x-netcom-plus-2xx.dts +@@ -222,10 +222,10 @@ &gpio3 { + "ModeA1", + "ModeA2", + "ModeA3", +- "NC", +- "NC", +- "NC", +- "NC", ++ "ModeB0", ++ "ModeB1", ++ "ModeB2", ++ "ModeB3", + "NC", + "NC", + "NC", +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch b/queue-6.6/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch new file mode 100644 index 0000000000..8be76e8b5b --- /dev/null +++ b/queue-6.6/arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch @@ -0,0 +1,43 @@ +From 55e9f2be1ed7814f58533fda3260070f0d206a77 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:15 +0200 +Subject: ARM: dts: omap3: beagle-xm: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit f7f3bc18300a230e0f1bfb17fc8889435c1e47f5 ] + +The "ti,twl4030-power-beagleboard-xm" compatible string is obsolete and +is not supported by any in-kernel driver. Currently, the kernel falls +back to the second entry, "ti,twl4030-power-idle-osc-off", to bind a +driver to this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: 9188883fd66e9 ("ARM: dts: Enable twl4030 off-idle configuration for selected omaps") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-3-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +index 08ee0f8ea68fd..71b39a923d37c 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-beagle-xm.dts +@@ -291,7 +291,7 @@ codec { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-beagleboard-xm", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch b/queue-6.6/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch new file mode 100644 index 0000000000..0c9cdf481b --- /dev/null +++ b/queue-6.6/arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch @@ -0,0 +1,43 @@ +From 83db94f8796099fccea647899012fbcf337d0c3b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 14 Sep 2025 21:25:16 +0200 +Subject: ARM: dts: omap3: n900: Correct obsolete TWL4030 power compatible + +From: Jihed Chaibi + +[ Upstream commit 3862123e9b56663c7a3e4a308e6e65bffe44f646 ] + +The "ti,twl4030-power-n900" compatible string is obsolete and is not +supported by any in-kernel driver. Currently, the kernel falls back to +the second entry, "ti,twl4030-power-idle-osc-off", to bind a driver to +this node. + +Make this fallback explicit by removing the obsolete board-specific +compatible. This preserves the existing functionality while making the +DTS compliant with the new, stricter 'ti,twl.yaml' binding. + +Fixes: daebabd578647 ("mfd: twl4030-power: Fix PM idle pin configuration to not conflict with regulators") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250914192516.164629-4-jihed.chaibi.dev@gmail.com +Signed-off-by: Kevin Hilman +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/ti/omap/omap3-n900.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +index 036e472b77beb..98f259dbcb0d5 100644 +--- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts ++++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts +@@ -508,7 +508,7 @@ twl_audio: audio { + }; + + twl_power: power { +- compatible = "ti,twl4030-power-n900", "ti,twl4030-power-idle-osc-off"; ++ compatible = "ti,twl4030-power-idle-osc-off"; + ti,use_poweroff; + }; + }; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-renesas-gose-remove-superfluous-port-propert.patch b/queue-6.6/arm-dts-renesas-gose-remove-superfluous-port-propert.patch new file mode 100644 index 0000000000..389b922e13 --- /dev/null +++ b/queue-6.6/arm-dts-renesas-gose-remove-superfluous-port-propert.patch @@ -0,0 +1,39 @@ +From ad77cb9365782e8efbe96ad92d02d36b88488ffd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 29 Sep 2025 11:36:02 +0200 +Subject: ARM: dts: renesas: gose: Remove superfluous port property + +From: Wolfram Sang + +[ Upstream commit 00df14f34615630f92f97c9d6790bd9d25c4242d ] + +'bus-width' is defined for the corresponding vin input port already. +No need to declare it in the output port again. Fixes: + + arch/arm/boot/dts/renesas/r8a7793-gose.dtb: composite-in@20 (adi,adv7180cp): ports:port@3:endpoint: Unevaluated properties are not allowed ('bus-width' was unexpected) + from schema $id: http://devicetree.org/schemas/media/i2c/adi,adv7180.yaml# + +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250929093616.17679-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r8a7793-gose.dts | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +index 9358fc7d0e9f6..e92de3ab33b5a 100644 +--- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts ++++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts +@@ -355,7 +355,6 @@ adv7180_in: endpoint { + port@3 { + reg = <3>; + adv7180_out: endpoint { +- bus-width = <8>; + remote-endpoint = <&vin1ep>; + }; + }; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch b/queue-6.6/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch new file mode 100644 index 0000000000..1363e0c005 --- /dev/null +++ b/queue-6.6/arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch @@ -0,0 +1,41 @@ +From 56aec39f1359003f12d0af8b1f448f205e056fa1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 7 Oct 2025 12:46:25 +0200 +Subject: ARM: dts: renesas: r9a06g032-rzn1d400-db: Drop invalid #cells + properties + +From: Wolfram Sang + +[ Upstream commit ca7fffb6e92a7c93604ea2bae0e1c89b20750937 ] + +The 'ethernet-ports' node in the SoC DTSI handles them already. Fixes: + + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dtb: switch@44050000 (renesas,r9a06g032-a5psw): Unevaluated properties are not allowed ('#address-cells', '#size-cells' were unexpected) + from schema $id: http://devicetree.org/schemas/net/dsa/renesas,rzn1-a5psw.yaml# + +Fixes: 5b6d7c3c5861ad4a ("ARM: dts: r9a06g032-rzn1d400-db: Add switch description") +Signed-off-by: Wolfram Sang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251007104624.19786-2-wsa+renesas@sang-engineering.com +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +index 31cdca3e623cd..5fa7acce47149 100644 +--- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts ++++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +@@ -126,8 +126,6 @@ &rtc0 { + + &switch { + status = "okay"; +- #address-cells = <1>; +- #size-cells = <0>; + + pinctrl-names = "default"; + pinctrl-0 = <&pins_eth3>, <&pins_eth4>, <&pins_mdio1>; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch b/queue-6.6/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..e63fbcf8b7 --- /dev/null +++ b/queue-6.6/arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From c9c8109510fabebc1412068d60a3e36eaba4de0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:16 +0100 +Subject: ARM: dts: samsung: exynos4210-i9100: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 863d69923bdb6f414d0a3f504f1dfaeacbc00b09 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: 8620cc2f99b7 ("ARM: dts: exynos: Add devicetree file for the Galaxy S2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-3-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-i9100.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +index a076a1dfe41f8..d7adf2bd8f87e 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +@@ -815,6 +815,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&vtf_reg>; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch b/queue-6.6/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..23cbdbcd96 --- /dev/null +++ b/queue-6.6/arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 6e23aeb956ddfebef5e1f692f4cef119675786ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:17 +0100 +Subject: ARM: dts: samsung: exynos4210-trats: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97cc9c346b2c9cde075b9420fc172137d2427711 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: a19f6efc01df ("ARM: dts: exynos: Enable WLAN support for the Trats board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-4-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-trats.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +index 95e0e01b6ff6b..6bd902cb8f4ad 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts +@@ -518,6 +518,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&tflash_reg>; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch b/queue-6.6/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch new file mode 100644 index 0000000000..358fd2af14 --- /dev/null +++ b/queue-6.6/arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch @@ -0,0 +1,43 @@ +From 0c74d730343e6d20412c3ba1710f7ef95ce32adc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:18 +0100 +Subject: ARM: dts: samsung: exynos4412-midas: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 2ff147fdfa99b8cbb8c2833e685fde7c42580ae6 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f77cbb9a3e5d ("ARM: dts: exynos: Add bcm4334 device node to Trats2") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-5-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4412-midas.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +index 7daf25865551b..a77e57645f217 100644 +--- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi ++++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +@@ -1440,6 +1440,7 @@ &sdhci_3 { + #address-cells = <1>; + #size-cells = <0>; + non-removable; ++ cap-power-off-card; + bus-width = <4>; + + mmc-pwrseq = <&wlan_pwrseq>; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch b/queue-6.6/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch new file mode 100644 index 0000000000..70a1a1ae4e --- /dev/null +++ b/queue-6.6/arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch @@ -0,0 +1,43 @@ +From eafa9483efcd4f332405714d5cb580f1cd1b7e3f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 11:26:15 +0100 +Subject: ARM: dts: samsung: universal_c210: turn off SDIO WLAN chip during + system suspend + +From: Marek Szyprowski + +[ Upstream commit 97aee67e2406ea381408915e606c5f86448f3949 ] + +Commit 8c3170628a9c ("wifi: brcmfmac: keep power during suspend if board +requires it") changed default behavior of the BRCMFMAC driver, which now +keeps SDIO card powered during system suspend to enable optional support +for WOWL. This feature is not supported by the legacy Exynos4 based +boards and leads to WLAN disfunction after system suspend/resume cycle. +Fix this by annotating SDIO host used by WLAN chip with +'cap-power-off-card' property, which should have been there from the +beginning. + +Fixes: f1b0ffaa686f ("ARM: dts: exynos: Enable WLAN support for the UniversalC210 board") +Signed-off-by: Marek Szyprowski +Link: https://patch.msgid.link/20251126102618.3103517-2-m.szyprowski@samsung.com +Signed-off-by: Krzysztof Kozlowski +Signed-off-by: Sasha Levin +--- + arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +index bdc30f8cf748f..91490693432b6 100644 +--- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts ++++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +@@ -610,6 +610,7 @@ &sdhci_3 { + #size-cells = <0>; + + non-removable; ++ cap-power-off-card; + bus-width = <4>; + mmc-pwrseq = <&wlan_pwrseq>; + vmmc-supply = <&ldo5_reg>; +-- +2.51.0 + diff --git a/queue-6.6/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch b/queue-6.6/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch new file mode 100644 index 0000000000..d1eded9f25 --- /dev/null +++ b/queue-6.6/arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch @@ -0,0 +1,50 @@ +From ddcd500694e44aeee06f584aeb194dd2a952e805 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 00:46:11 +0200 +Subject: ARM: dts: stm32: stm32mp157c-phycore: Fix STMPE811 touchscreen node + properties + +From: Jihed Chaibi + +[ Upstream commit e40b061cd379f4897e705d17cf1b4572ad0f3963 ] + +Move st,adc-freq, st,mod-12b, st,ref-sel, and st,sample-time properties +from the touchscreen subnode to the parent touch@44 node. These properties +are defined in the st,stmpe.yaml schema for the parent node, not the +touchscreen subnode, resolving the validation error about unevaluated +properties. + +Fixes: 27538a18a4fcc ("ARM: dts: stm32: add STM32MP1-based Phytec SoM") +Signed-off-by: Jihed Chaibi +Link: https://lore.kernel.org/r/20250915224611.169980-1-jihed.chaibi.dev@gmail.com +Signed-off-by: Alexandre Torgue +Signed-off-by: Sasha Levin +--- + .../boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +index 4e8b2d2b30c7a..7dfe1fbfbfedc 100644 +--- a/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi ++++ b/arch/arm/boot/dts/st/stm32mp157c-phycore-stm32mp15-som.dtsi +@@ -185,13 +185,13 @@ touch@44 { + interrupt-parent = <&gpioi>; + vio-supply = <&v3v3>; + vcc-supply = <&v3v3>; ++ st,sample-time = <4>; ++ st,mod-12b = <1>; ++ st,ref-sel = <0>; ++ st,adc-freq = <1>; + + touchscreen { + compatible = "st,stmpe-ts"; +- st,sample-time = <4>; +- st,mod-12b = <1>; +- st,ref-sel = <0>; +- st,adc-freq = <1>; + st,ave-ctrl = <1>; + st,touch-det-delay = <2>; + st,settling = <2>; +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch b/queue-6.6/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch new file mode 100644 index 0000000000..ae1725690f --- /dev/null +++ b/queue-6.6/arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch @@ -0,0 +1,38 @@ +From 64ecf7d8f55ac12a959711f2410ddbfe0688c033 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:45 -0700 +Subject: arm64: dts: freescale: imx8mp-venice-gw7905-2x: remove duplicate + usdhc1 props + +From: Tim Harvey + +[ Upstream commit 8b7e58ab4a02601a0e86e9f9701d4612038d8b29 ] + +Remove the un-intended duplicate properties from usdhc1. + +Fixes: 0d5b288c2110e ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index 560c68e4da6dc..f541360cb5548 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -401,9 +401,6 @@ &usdhc1 { + bus-width = <4>; + non-removable; + status = "okay"; +- bus-width = <4>; +- non-removable; +- status = "okay"; + }; + + /* eMMC */ +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch b/queue-6.6/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch new file mode 100644 index 0000000000..46abbbe509 --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch @@ -0,0 +1,46 @@ +From 5b61e9cb59c046d62145b130ffcc3715b52f4790 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:49 -0700 +Subject: arm64: dts: imx8mm-venice-gw72xx: remove unused sdhc1 pinctrl + +From: Tim Harvey + +[ Upstream commit d949b8d12d6e8fa119bca10d3157cd42e810f6f7 ] + +The SDHC1 interface is not used on the imx8mm-venice-gw72xx. Remove the +unused pinctrl_usdhc1 iomux node. + +Fixes: 6f30b27c5ef5 ("arm64: dts: imx8mm: Add Gateworks i.MX 8M Mini Development Kits") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../boot/dts/freescale/imx8mm-venice-gw72xx.dtsi | 11 ----------- + 1 file changed, 11 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +index 570992a52b759..7263bbf0f0520 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mm-venice-gw72xx.dtsi +@@ -337,17 +337,6 @@ MX8MM_IOMUXC_UART4_TXD_UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MM_IOMUXC_SD1_CLK_USDHC1_CLK 0x190 +- MX8MM_IOMUXC_SD1_CMD_USDHC1_CMD 0x1d0 +- MX8MM_IOMUXC_SD1_DATA0_USDHC1_DATA0 0x1d0 +- MX8MM_IOMUXC_SD1_DATA1_USDHC1_DATA1 0x1d0 +- MX8MM_IOMUXC_SD1_DATA2_USDHC1_DATA2 0x1d0 +- MX8MM_IOMUXC_SD1_DATA3_USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MM_IOMUXC_SD2_CLK_USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch b/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch new file mode 100644 index 0000000000..888a2b4b2b --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch @@ -0,0 +1,87 @@ +From e42b485683258ca70fdef2c29b9e914613f1df1c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:51 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board sdhc1 + +From: Tim Harvey + +[ Upstream commit 9db04b310ef99b546e4240c55842e81b06b78579 ] + +SDHC1 on the GW702x SOM routes to a connector for use on a baseboard +and as such are defined in the baseboard device-trees. + +Remove it from the gw702x SOM device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 20 ------------------- + .../dts/freescale/imx8mp-venice-gw72xx.dtsi | 11 ---------- + 2 files changed, 31 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index ac5b3a8ce729b..de21faeafd099 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -380,15 +380,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board */ +-&usdhc1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_usdhc1>; +- bus-width = <4>; +- non-removable; +- status = "okay"; +-}; +- + /* eMMC */ + &usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; +@@ -489,17 +480,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX8MP_IOMUXC_NAND_WE_B__USDHC3_CLK 0x190 +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +index f3bab22d5e683..fc1ee675c88de 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw72xx.dtsi +@@ -310,17 +310,6 @@ MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x140 + >; + }; + +- pinctrl_usdhc1: usdhc1grp { +- fsl,pins = < +- MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +- MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 +- MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 +- MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 +- MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 +- MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 +- >; +- }; +- + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX8MP_IOMUXC_SD2_CLK__USDHC2_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch b/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch new file mode 100644 index 0000000000..802de1f29f --- /dev/null +++ b/queue-6.6/arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch @@ -0,0 +1,85 @@ +From f7b4793547b2f35f951aec156b0d215cd09f5195 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 08:44:50 -0700 +Subject: arm64: dts: imx8mp-venice-gw702x: remove off-board uart + +From: Tim Harvey + +[ Upstream commit effe98060f70eb96e142f656e750d6af275ceac3 ] + +UART1 and UART3 go to a connector for use on a baseboard and as such are +defined in the baseboard device-trees. Remove them from the gw702x SOM +device-tree. + +Fixes: 0d5b288c2110 ("arm64: dts: freescale: Add imx8mp-venice-gw7905-2x") +Signed-off-by: Tim Harvey +Reviewed-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + .../dts/freescale/imx8mp-venice-gw702x.dtsi | 28 ------------------- + 1 file changed, 28 deletions(-) + +diff --git a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +index f541360cb5548..ac5b3a8ce729b 100644 +--- a/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi ++++ b/arch/arm64/boot/dts/freescale/imx8mp-venice-gw702x.dtsi +@@ -373,13 +373,6 @@ &i2c3 { + status = "okay"; + }; + +-/* off-board header */ +-&uart1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart1>; +- status = "okay"; +-}; +- + /* console */ + &uart2 { + pinctrl-names = "default"; +@@ -387,13 +380,6 @@ &uart2 { + status = "okay"; + }; + +-/* off-board header */ +-&uart3 { +- pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_uart3>; +- status = "okay"; +-}; +- + /* off-board */ + &usdhc1 { + pinctrl-names = "default"; +@@ -496,13 +482,6 @@ MX8MP_IOMUXC_I2C3_SDA__GPIO5_IO19 0x400001c2 + >; + }; + +- pinctrl_uart1: uart1grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART1_RXD__UART1_DCE_RX 0x140 +- MX8MP_IOMUXC_UART1_TXD__UART1_DCE_TX 0x140 +- >; +- }; +- + pinctrl_uart2: uart2grp { + fsl,pins = < + MX8MP_IOMUXC_UART2_RXD__UART2_DCE_RX 0x140 +@@ -510,13 +489,6 @@ MX8MP_IOMUXC_UART2_TXD__UART2_DCE_TX 0x140 + >; + }; + +- pinctrl_uart3: uart3grp { +- fsl,pins = < +- MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 +- MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 +- >; +- }; +- + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch b/queue-6.6/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch new file mode 100644 index 0000000000..addbd5a65a --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch @@ -0,0 +1,40 @@ +From 3aa3d6dc09dd9dd20a847440eb1594f8cf86ac56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:01 +0300 +Subject: arm64: dts: qcom: msm8996: add interconnect paths to USB2 controller + +From: Dmitry Baryshkov + +[ Upstream commit 242f7558e7bf54cb63c06506f7b0630dd67d45a4 ] + +Add the missing interconnects to the USB2 host. The Fixes tag points to +the commit which broke probing of the USB host on that platform. + +Fixes: 130733a10079 ("interconnect: qcom: msm8996: Promote to core_initcall") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Acked-by: Bjorn Andersson +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-2-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/msm8996.dtsi | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi +index 70ef8c83e7b9f..473d72d2c7b1a 100644 +--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi ++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi +@@ -3432,6 +3432,9 @@ usb2: usb@76f8800 { + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <60000000>; + ++ interconnects = <&pnoc MASTER_USB_HS &bimc SLAVE_EBI_CH0>, ++ <&bimc MASTER_AMPSS_M0 &pnoc SLAVE_USB_HS>; ++ interconnect-names = "usb-ddr", "apps-usb"; + power-domains = <&gcc USB30_GDSC>; + qcom,select-utmi-as-pipe-clk; + status = "disabled"; +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch b/queue-6.6/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch new file mode 100644 index 0000000000..0a709bf093 --- /dev/null +++ b/queue-6.6/arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch @@ -0,0 +1,41 @@ +From f407170bf42f1b1285d45fd4ec3c4849c5b7b04b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 27 Sep 2025 13:20:28 +0200 +Subject: arm64: dts: qcom: sdm845-oneplus: Correct gpio used for slider + +From: Gergo Koteles + +[ Upstream commit d7ec7d34237498fab7a6afed8da4b7139b0e387c ] + +The previous GPIO numbers were wrong. Update them to the correct +ones and fix the label. + +Fixes: 288ef8a42612 ("arm64: dts: sdm845: add oneplus6/6t devices") +Signed-off-by: Gergo Koteles +Signed-off-by: David Heidelberg +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20250927-slider-correct-v1-1-fb8cc7fdcedf@ixit.cz +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +index 9322b92a1e682..bccc52e01da38 100644 +--- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi ++++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +@@ -780,8 +780,8 @@ hall_sensor_default: hall-sensor-default-state { + bias-disable; + }; + +- tri_state_key_default: tri-state-key-default-state { +- pins = "gpio40", "gpio42", "gpio26"; ++ alert_slider_default: alert-slider-default-state { ++ pins = "gpio126", "gpio52", "gpio24"; + function = "gpio"; + drive-strength = <2>; + bias-disable; +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch b/queue-6.6/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch new file mode 100644 index 0000000000..5784a603e8 --- /dev/null +++ b/queue-6.6/arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch @@ -0,0 +1,48 @@ +From 0b1f2cca8b4cafa37deb852858a7feac1bf7354d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:30 +0000 +Subject: arm64: dts: rockchip: Add eeprom vcc-supply for Radxa ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 3069ff1930aa71e125874c780ffaa6caeda5800a ] + +The VCC supply for the BL24C16 EEPROM chip found on Radxa ROCK 5A is +vcc_3v3_pmu, which is routed to vcc_3v3_s3 via a zero-ohm resistor. [1] +Describe this supply. + +[1] https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.4, p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-3-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index f60243e2b3c39..cd8bd50b35778 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -189,6 +189,7 @@ eeprom: eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; ++ vcc-supply = <&vcc_3v3_pmu>; + }; + }; + +@@ -518,7 +519,7 @@ regulator-state-mem { + }; + }; + +- vcc_3v3_s3: dcdc-reg8 { ++ vcc_3v3_pmu: vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch b/queue-6.6/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch new file mode 100644 index 0000000000..9e93def79e --- /dev/null +++ b/queue-6.6/arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch @@ -0,0 +1,58 @@ +From d1678258bc0f4e3b5b0e5ccc1b61f0b55220d177 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 03:51:29 +0000 +Subject: arm64: dts: rockchip: Move the EEPROM to correct I2C bus on Radxa + ROCK 5A + +From: FUKAUMI Naoki + +[ Upstream commit 92e6e0b0e595afdda6296c760551ad3ffe9d5231 ] + +The BL24C16 EEPROM chip found on Radxa ROCK 5A is connected to the +i2c0 bus, [1] so move the eeprom node from the i2c2 bus to the i2c0 +bus. + +[1] Link: https://dl.radxa.com/rock5/5a/docs/hw/radxa_rock5a_V1.1_sch.pdf p.19 + +Fixes: 89c880808cff8 ("arm64: dts: rockchip: add I2C EEPROM to rock-5a") +Signed-off-by: FUKAUMI Naoki +Link: https://patch.msgid.link/20251112035133.28753-2-naoki@radxa.com +Signed-off-by: Heiko Stuebner +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +index 68763714f7f7b..f60243e2b3c39 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts ++++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +@@ -184,6 +184,12 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; ++ ++ eeprom: eeprom@50 { ++ compatible = "belling,bl24c16a", "atmel,24c16"; ++ reg = <0x50>; ++ pagesize = <16>; ++ }; + }; + + &i2c2 { +@@ -205,12 +211,6 @@ regulator-state-mem { + regulator-off-in-suspend; + }; + }; +- +- eeprom: eeprom@50 { +- compatible = "belling,bl24c16a", "atmel,24c16"; +- reg = <0x50>; +- pagesize = <16>; +- }; + }; + + &i2c3 { +-- +2.51.0 + diff --git a/queue-6.6/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch b/queue-6.6/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch new file mode 100644 index 0000000000..9e94fadcac --- /dev/null +++ b/queue-6.6/arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch @@ -0,0 +1,40 @@ +From 77b7cd763d07ce50d3f5baea64ddc996238c95c5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Sep 2025 14:33:42 -0500 +Subject: arm64: dts: ti: k3-am62p: Fix memory ranges for GPU + +From: Randolph Sapp + +[ Upstream commit 76546090b1726118cd6fb3db7159fc2a3fdda8a0 ] + +Update the memory region listed in the k3-am62p.dtsi for the BXS-4-64 +GPU to match the Main Memory Map described in the TRM [1]. + +[1] https://www.ti.com/lit/ug/spruj83b/spruj83b.pdf + +Fixes: 29075cc09f43 ("arm64: dts: ti: Introduce AM62P5 family of SoCs") +Signed-off-by: Randolph Sapp +Reviewed-by: Michael Walle +Link: https://patch.msgid.link/20250919193341.707660-2-rs@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +--- + arch/arm64/boot/dts/ti/k3-am62p.dtsi | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm64/boot/dts/ti/k3-am62p.dtsi b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +index dc0a8e94e9ace..0e0241e746fb1 100644 +--- a/arch/arm64/boot/dts/ti/k3-am62p.dtsi ++++ b/arch/arm64/boot/dts/ti/k3-am62p.dtsi +@@ -59,7 +59,7 @@ cbass_main: bus@f0000 { + <0x00 0x01000000 0x00 0x01000000 0x00 0x01b28400>, /* First peripheral window */ + <0x00 0x08000000 0x00 0x08000000 0x00 0x00200000>, /* Main CPSW */ + <0x00 0x0e000000 0x00 0x0e000000 0x00 0x01d20000>, /* Second peripheral window */ +- <0x00 0x0fd00000 0x00 0x0fd00000 0x00 0x00020000>, /* GPU */ ++ <0x00 0x0fd80000 0x00 0x0fd80000 0x00 0x00080000>, /* GPU */ + <0x00 0x20000000 0x00 0x20000000 0x00 0x0a008000>, /* Third peripheral window */ + <0x00 0x30040000 0x00 0x30040000 0x00 0x00080000>, /* PRUSS-M */ + <0x00 0x30101000 0x00 0x30101000 0x00 0x00010100>, /* CSI window */ +-- +2.51.0 + diff --git a/queue-6.6/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch b/queue-6.6/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch new file mode 100644 index 0000000000..bbb5d10f9f --- /dev/null +++ b/queue-6.6/asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch @@ -0,0 +1,39 @@ +From db4c322d94f2b86d4563f3bc1fad7302389daa0d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 14:45:09 +0800 +Subject: ASoC: fsl_xcvr: clear the channel status control memory + +From: Shengjiu Wang + +[ Upstream commit 73b97d46dde64fa184d47865d4a532d818c3a007 ] + +memset_io() writes memory byte by byte with __raw_writeb() on the arm +platform if the size is word. but XCVR data RAM memory can't be accessed +with byte address, so with memset_io() the channel status control memory +is not really cleared, use writel_relaxed() instead. + +Fixes: 28564486866f ("ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver") +Signed-off-by: Shengjiu Wang +Link: https://patch.msgid.link/20251126064509.1900974-1-shengjiu.wang@nxp.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_xcvr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c +index 1d7791c7fb4ec..90a0a24c05d84 100644 +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1195,7 +1195,7 @@ static irqreturn_t irq0_isr(int irq, void *devid) + bitrev32(val); + } + /* clear CS control register */ +- memset_io(reg_ctrl, 0, sizeof(val)); ++ writel_relaxed(0, reg_ctrl); + } + } else { + regmap_read(xcvr->regmap, FSL_XCVR_RX_CS_DATA_0, +-- +2.51.0 + diff --git a/queue-6.6/asoc-intel-catpt-fix-error-path-in-hw_params.patch b/queue-6.6/asoc-intel-catpt-fix-error-path-in-hw_params.patch new file mode 100644 index 0000000000..76a7505de2 --- /dev/null +++ b/queue-6.6/asoc-intel-catpt-fix-error-path-in-hw_params.patch @@ -0,0 +1,41 @@ +From fbd2676ec2c9be7209b67f1a95aca5b2831dd99b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:55:20 +0100 +Subject: ASoC: Intel: catpt: Fix error path in hw_params() + +From: Cezary Rojewski + +[ Upstream commit 86a5b621be658fc8fe594ca6db317d64de30cce1 ] + +Do not leave any resources hanging on the DSP side if +applying user settings fails. + +Fixes: 768a3a3b327d ("ASoC: Intel: catpt: Optimize applying user settings") +Signed-off-by: Cezary Rojewski +Reviewed-by: Andy Shevchenko +Link: https://patch.msgid.link/20251126095523.3925364-4-cezary.rojewski@intel.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/intel/catpt/pcm.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/sound/soc/intel/catpt/pcm.c b/sound/soc/intel/catpt/pcm.c +index f1a5cb825ff1f..10d1c15857bfa 100644 +--- a/sound/soc/intel/catpt/pcm.c ++++ b/sound/soc/intel/catpt/pcm.c +@@ -417,8 +417,10 @@ static int catpt_dai_hw_params(struct snd_pcm_substream *substream, + return CATPT_IPC_ERROR(ret); + + ret = catpt_dai_apply_usettings(dai, stream); +- if (ret) ++ if (ret) { ++ catpt_ipc_free_stream(cdev, stream->info.stream_hw_id); + return ret; ++ } + + stream->allocated = true; + return 0; +-- +2.51.0 + diff --git a/queue-6.6/backlight-led-bl-add-devlink-to-supplier-leds.patch b/queue-6.6/backlight-led-bl-add-devlink-to-supplier-leds.patch new file mode 100644 index 0000000000..e28f8346af --- /dev/null +++ b/queue-6.6/backlight-led-bl-add-devlink-to-supplier-leds.patch @@ -0,0 +1,102 @@ +From 109cbf8e924c0217b8002dd5816bba15f5d665b6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 May 2025 22:19:11 +0200 +Subject: backlight: led-bl: Add devlink to supplier LEDs + +From: Luca Ceresoli + +[ Upstream commit 9341d6698f4cfdfc374fb6944158d111ebe16a9d ] + +LED Backlight is a consumer of one or multiple LED class devices, but +devlink is currently unable to create correct supplier-producer links when +the supplier is a class device. It creates instead a link where the +supplier is the parent of the expected device. + +One consequence is that removal order is not correctly enforced. + +Issues happen for example with the following sections in a device tree +overlay: + + // An LED driver chip + pca9632@62 { + compatible = "nxp,pca9632"; + reg = <0x62>; + + // ... + + addon_led_pwm: led-pwm@3 { + reg = <3>; + label = "addon:led:pwm"; + }; + }; + + backlight-addon { + compatible = "led-backlight"; + leds = <&addon_led_pwm>; + brightness-levels = <255>; + default-brightness-level = <255>; + }; + +In this example, the devlink should be created between the backlight-addon +(consumer) and the pca9632@62 (supplier). Instead it is created between the +backlight-addon (consumer) and the parent of the pca9632@62, which is +typically the I2C bus adapter. + +On removal of the above overlay, the LED driver can be removed before the +backlight device, resulting in: + + Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 + ... + Call trace: + led_put+0xe0/0x140 + devm_led_release+0x6c/0x98 + +Another way to reproduce the bug without any device tree overlays is +unbinding the LED class device (pca9632@62) before unbinding the consumer +(backlight-addon): + + echo 11-0062 >/sys/bus/i2c/drivers/leds-pca963x/unbind + echo ...backlight-dock >/sys/bus/platform/drivers/led-backlight/unbind + +Fix by adding a devlink between the consuming led-backlight device and the +supplying LED device, as other drivers and subsystems do as well. + +Fixes: ae232e45acf9 ("backlight: add led-backlight driver") +Signed-off-by: Luca Ceresoli +Reviewed-by: Daniel Thompson (RISCstar) +Reviewed-by: Herve Codina +Tested-by: Alexander Sverdlin +Link: https://patch.msgid.link/20250519-led-backlight-add-devlink-to-supplier-class-device-v6-1-845224aeb2ce@bootlin.com +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/video/backlight/led_bl.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/video/backlight/led_bl.c b/drivers/video/backlight/led_bl.c +index 0e53e427a91dc..9089d17200ec7 100644 +--- a/drivers/video/backlight/led_bl.c ++++ b/drivers/video/backlight/led_bl.c +@@ -209,6 +209,19 @@ static int led_bl_probe(struct platform_device *pdev) + return PTR_ERR(priv->bl_dev); + } + ++ for (i = 0; i < priv->nb_leds; i++) { ++ struct device_link *link; ++ ++ link = device_link_add(&pdev->dev, priv->leds[i]->dev->parent, ++ DL_FLAG_AUTOREMOVE_CONSUMER); ++ if (!link) { ++ dev_err(&pdev->dev, "Failed to add devlink (consumer %s, supplier %s)\n", ++ dev_name(&pdev->dev), dev_name(priv->leds[i]->dev->parent)); ++ backlight_device_unregister(priv->bl_dev); ++ return -EINVAL; ++ } ++ } ++ + for (i = 0; i < priv->nb_leds; i++) { + mutex_lock(&priv->leds[i]->led_access); + led_sysfs_disable(priv->leds[i]); +-- +2.51.0 + diff --git a/queue-6.6/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch b/queue-6.6/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch new file mode 100644 index 0000000000..b7e79b0c34 --- /dev/null +++ b/queue-6.6/backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch @@ -0,0 +1,50 @@ +From df86e5085e7ed67ff7cd0c3038b8e43522382d3a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 22:09:16 -0800 +Subject: backlight: lp855x: Fix lp855x.h kernel-doc warnings + +From: Randy Dunlap + +[ Upstream commit 2d45db63260c6ae3cf007361e04a1c41bd265084 ] + +Add a missing struct short description and a missing leading " *" to +lp855x.h to avoid kernel-doc warnings: + +Warning: include/linux/platform_data/lp855x.h:126 missing initial short + description on line: + * struct lp855x_platform_data +Warning: include/linux/platform_data/lp855x.h:131 bad line: + Only valid when mode is PWM_BASED. + +Fixes: 7be865ab8634 ("backlight: new backlight driver for LP855x devices") +Signed-off-by: Randy Dunlap +Reviewed-by: Daniel Thompson (RISCstar) +Link: https://patch.msgid.link/20251111060916.1995920-1-rdunlap@infradead.org +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + include/linux/platform_data/lp855x.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/platform_data/lp855x.h b/include/linux/platform_data/lp855x.h +index ab222dd05bbc2..3b4a891acefe9 100644 +--- a/include/linux/platform_data/lp855x.h ++++ b/include/linux/platform_data/lp855x.h +@@ -124,12 +124,12 @@ struct lp855x_rom_data { + }; + + /** +- * struct lp855x_platform_data ++ * struct lp855x_platform_data - lp855 platform-specific data + * @name : Backlight driver name. If it is not defined, default name is set. + * @device_control : value of DEVICE CONTROL register + * @initial_brightness : initial value of backlight brightness + * @period_ns : platform specific pwm period value. unit is nano. +- Only valid when mode is PWM_BASED. ++ * Only valid when mode is PWM_BASED. + * @size_program : total size of lp855x_rom_data + * @rom_data : list of new eeprom/eprom registers + */ +-- +2.51.0 + diff --git a/queue-6.6/block-mq-deadline-introduce-dd_start_request.patch b/queue-6.6/block-mq-deadline-introduce-dd_start_request.patch new file mode 100644 index 0000000000..23e643ae1b --- /dev/null +++ b/queue-6.6/block-mq-deadline-introduce-dd_start_request.patch @@ -0,0 +1,74 @@ +From 01ba5be1cc0a82131bae24f8cfd96c94415ace79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:02 -0700 +Subject: block/mq-deadline: Introduce dd_start_request() + +From: Bart Van Assche + +[ Upstream commit 93a358af59c6e8ab00b57cfdb1c437516a4948ca ] + +Prepare for adding a second caller of this function. No functionality +has been changed. + +Cc: Damien Le Moal +Cc: Yu Kuai +Cc: chengkaitao +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moal +Signed-off-by: Jens Axboe +Stable-dep-of: d60055cf5270 ("block/mq-deadline: Switch back to a single dispatch list") +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 23638b03d7b3d..b62f534a389e3 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -338,6 +338,19 @@ static bool started_after(struct deadline_data *dd, struct request *rq, + return time_after(start_time, latest_start); + } + ++static struct request *dd_start_request(struct deadline_data *dd, ++ enum dd_data_dir data_dir, ++ struct request *rq) ++{ ++ u8 ioprio_class = dd_rq_ioclass(rq); ++ enum dd_prio prio = ioprio_class_to_prio[ioprio_class]; ++ ++ dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); ++ dd->per_prio[prio].stats.dispatched++; ++ rq->rq_flags |= RQF_STARTED; ++ return rq; ++} ++ + /* + * deadline_dispatch_requests selects the best request according to + * read/write expire, fifo_batch, etc and with a start time <= @latest_start. +@@ -348,8 +361,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + { + struct request *rq, *next_rq; + enum dd_data_dir data_dir; +- enum dd_prio prio; +- u8 ioprio_class; + + lockdep_assert_held(&dd->lock); + +@@ -443,12 +454,7 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + dd->batching++; + deadline_move_request(dd, per_prio, rq); + done: +- ioprio_class = dd_rq_ioclass(rq); +- prio = ioprio_class_to_prio[ioprio_class]; +- dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); +- dd->per_prio[prio].stats.dispatched++; +- rq->rq_flags |= RQF_STARTED; +- return rq; ++ return dd_start_request(dd, data_dir, rq); + } + + /* +-- +2.51.0 + diff --git a/queue-6.6/block-mq-deadline-remove-support-for-zone-write-lock.patch b/queue-6.6/block-mq-deadline-remove-support-for-zone-write-lock.patch new file mode 100644 index 0000000000..95c8c3b638 --- /dev/null +++ b/queue-6.6/block-mq-deadline-remove-support-for-zone-write-lock.patch @@ -0,0 +1,320 @@ +From bf2022eaa2291ad1243b0711d5bd03ba4105ffbb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 8 Apr 2024 10:41:21 +0900 +Subject: block: mq-deadline: Remove support for zone write locking + +From: Damien Le Moal + +[ Upstream commit fde02699c242e88a71286677d27cc890a959b67f ] + +With the block layer generic plugging of write operations for zoned +block devices, mq-deadline, or any other scheduler, can only ever +see at most one write operation per zone at any time. There is thus no +sequentiality requirements for these writes and thus no need to tightly +control the dispatching of write requests using zone write locking. + +Remove all the code that implement this control in the mq-deadline +scheduler and remove advertizing support for the +ELEVATOR_F_ZBD_SEQ_WRITE elevator feature. + +Signed-off-by: Damien Le Moal +Reviewed-by: Hannes Reinecke +Reviewed-by: Christoph Hellwig +Reviewed-by: Bart Van Assche +Tested-by: Hans Holmberg +Tested-by: Dennis Maisenbacher +Reviewed-by: Martin K. Petersen +Link: https://lore.kernel.org/r/20240408014128.205141-22-dlemoal@kernel.org +Signed-off-by: Jens Axboe +Stable-dep-of: d60055cf5270 ("block/mq-deadline: Switch back to a single dispatch list") +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 176 ++------------------------------------------ + 1 file changed, 6 insertions(+), 170 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index 78a8aa204c156..23638b03d7b3d 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -102,7 +102,6 @@ struct deadline_data { + int prio_aging_expire; + + spinlock_t lock; +- spinlock_t zone_lock; + }; + + /* Maps an I/O priority class to a deadline scheduler priority. */ +@@ -157,8 +156,7 @@ deadline_latter_request(struct request *rq) + } + + /* +- * Return the first request for which blk_rq_pos() >= @pos. For zoned devices, +- * return the first request after the start of the zone containing @pos. ++ * Return the first request for which blk_rq_pos() >= @pos. + */ + static inline struct request *deadline_from_pos(struct dd_per_prio *per_prio, + enum dd_data_dir data_dir, sector_t pos) +@@ -170,14 +168,6 @@ static inline struct request *deadline_from_pos(struct dd_per_prio *per_prio, + return NULL; + + rq = rb_entry_rq(node); +- /* +- * A zoned write may have been requeued with a starting position that +- * is below that of the most recently dispatched request. Hence, for +- * zoned writes, start searching from the start of a zone. +- */ +- if (blk_rq_is_seq_zoned_write(rq)) +- pos = round_down(pos, rq->q->limits.chunk_sectors); +- + while (node) { + rq = rb_entry_rq(node); + if (blk_rq_pos(rq) >= pos) { +@@ -308,36 +298,6 @@ static inline bool deadline_check_fifo(struct dd_per_prio *per_prio, + return time_is_before_eq_jiffies((unsigned long)rq->fifo_time); + } + +-/* +- * Check if rq has a sequential request preceding it. +- */ +-static bool deadline_is_seq_write(struct deadline_data *dd, struct request *rq) +-{ +- struct request *prev = deadline_earlier_request(rq); +- +- if (!prev) +- return false; +- +- return blk_rq_pos(prev) + blk_rq_sectors(prev) == blk_rq_pos(rq); +-} +- +-/* +- * Skip all write requests that are sequential from @rq, even if we cross +- * a zone boundary. +- */ +-static struct request *deadline_skip_seq_writes(struct deadline_data *dd, +- struct request *rq) +-{ +- sector_t pos = blk_rq_pos(rq); +- +- do { +- pos += blk_rq_sectors(rq); +- rq = deadline_latter_request(rq); +- } while (rq && blk_rq_pos(rq) == pos); +- +- return rq; +-} +- + /* + * For the specified data direction, return the next request to + * dispatch using arrival ordered lists. +@@ -346,40 +306,10 @@ static struct request * + deadline_fifo_request(struct deadline_data *dd, struct dd_per_prio *per_prio, + enum dd_data_dir data_dir) + { +- struct request *rq, *rb_rq, *next; +- unsigned long flags; +- + if (list_empty(&per_prio->fifo_list[data_dir])) + return NULL; + +- rq = rq_entry_fifo(per_prio->fifo_list[data_dir].next); +- if (data_dir == DD_READ || !blk_queue_is_zoned(rq->q)) +- return rq; +- +- /* +- * Look for a write request that can be dispatched, that is one with +- * an unlocked target zone. For some HDDs, breaking a sequential +- * write stream can lead to lower throughput, so make sure to preserve +- * sequential write streams, even if that stream crosses into the next +- * zones and these zones are unlocked. +- */ +- spin_lock_irqsave(&dd->zone_lock, flags); +- list_for_each_entry_safe(rq, next, &per_prio->fifo_list[DD_WRITE], +- queuelist) { +- /* Check whether a prior request exists for the same zone. */ +- rb_rq = deadline_from_pos(per_prio, data_dir, blk_rq_pos(rq)); +- if (rb_rq && blk_rq_pos(rb_rq) < blk_rq_pos(rq)) +- rq = rb_rq; +- if (blk_req_can_dispatch_to_zone(rq) && +- (blk_queue_nonrot(rq->q) || +- !deadline_is_seq_write(dd, rq))) +- goto out; +- } +- rq = NULL; +-out: +- spin_unlock_irqrestore(&dd->zone_lock, flags); +- +- return rq; ++ return rq_entry_fifo(per_prio->fifo_list[data_dir].next); + } + + /* +@@ -390,36 +320,8 @@ static struct request * + deadline_next_request(struct deadline_data *dd, struct dd_per_prio *per_prio, + enum dd_data_dir data_dir) + { +- struct request *rq; +- unsigned long flags; +- +- rq = deadline_from_pos(per_prio, data_dir, +- per_prio->latest_pos[data_dir]); +- if (!rq) +- return NULL; +- +- if (data_dir == DD_READ || !blk_queue_is_zoned(rq->q)) +- return rq; +- +- /* +- * Look for a write request that can be dispatched, that is one with +- * an unlocked target zone. For some HDDs, breaking a sequential +- * write stream can lead to lower throughput, so make sure to preserve +- * sequential write streams, even if that stream crosses into the next +- * zones and these zones are unlocked. +- */ +- spin_lock_irqsave(&dd->zone_lock, flags); +- while (rq) { +- if (blk_req_can_dispatch_to_zone(rq)) +- break; +- if (blk_queue_nonrot(rq->q)) +- rq = deadline_latter_request(rq); +- else +- rq = deadline_skip_seq_writes(dd, rq); +- } +- spin_unlock_irqrestore(&dd->zone_lock, flags); +- +- return rq; ++ return deadline_from_pos(per_prio, data_dir, ++ per_prio->latest_pos[data_dir]); + } + + /* +@@ -525,10 +427,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + rq = next_rq; + } + +- /* +- * For a zoned block device, if we only have writes queued and none of +- * them can be dispatched, rq will be NULL. +- */ + if (!rq) + return NULL; + +@@ -549,10 +447,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + prio = ioprio_class_to_prio[ioprio_class]; + dd->per_prio[prio].latest_pos[data_dir] = blk_rq_pos(rq); + dd->per_prio[prio].stats.dispatched++; +- /* +- * If the request needs its target zone locked, do it. +- */ +- blk_req_zone_write_lock(rq); + rq->rq_flags |= RQF_STARTED; + return rq; + } +@@ -736,7 +630,6 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) + dd->fifo_batch = fifo_batch; + dd->prio_aging_expire = prio_aging_expire; + spin_lock_init(&dd->lock); +- spin_lock_init(&dd->zone_lock); + + /* We dispatch from request queue wide instead of hw queue */ + blk_queue_flag_set(QUEUE_FLAG_SQ_SCHED, q); +@@ -818,12 +711,6 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + + lockdep_assert_held(&dd->lock); + +- /* +- * This may be a requeue of a write request that has locked its +- * target zone. If it is the case, this releases the zone lock. +- */ +- blk_req_zone_write_unlock(rq); +- + prio = ioprio_class_to_prio[ioprio_class]; + per_prio = &dd->per_prio[prio]; + if (!rq->elv.priv[0]) { +@@ -855,18 +742,6 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + */ + rq->fifo_time = jiffies + dd->fifo_expire[data_dir]; + insert_before = &per_prio->fifo_list[data_dir]; +-#ifdef CONFIG_BLK_DEV_ZONED +- /* +- * Insert zoned writes such that requests are sorted by +- * position per zone. +- */ +- if (blk_rq_is_seq_zoned_write(rq)) { +- struct request *rq2 = deadline_latter_request(rq); +- +- if (rq2 && blk_rq_zone_no(rq2) == blk_rq_zone_no(rq)) +- insert_before = &rq2->queuelist; +- } +-#endif + list_add_tail(&rq->queuelist, insert_before); + } + } +@@ -901,33 +776,8 @@ static void dd_prepare_request(struct request *rq) + rq->elv.priv[0] = NULL; + } + +-static bool dd_has_write_work(struct blk_mq_hw_ctx *hctx) +-{ +- struct deadline_data *dd = hctx->queue->elevator->elevator_data; +- enum dd_prio p; +- +- for (p = 0; p <= DD_PRIO_MAX; p++) +- if (!list_empty_careful(&dd->per_prio[p].fifo_list[DD_WRITE])) +- return true; +- +- return false; +-} +- + /* + * Callback from inside blk_mq_free_request(). +- * +- * For zoned block devices, write unlock the target zone of +- * completed write requests. Do this while holding the zone lock +- * spinlock so that the zone is never unlocked while deadline_fifo_request() +- * or deadline_next_request() are executing. This function is called for +- * all requests, whether or not these requests complete successfully. +- * +- * For a zoned block device, __dd_dispatch_request() may have stopped +- * dispatching requests if all the queued requests are write requests directed +- * at zones that are already locked due to on-going write requests. To ensure +- * write request dispatch progress in this case, mark the queue as needing a +- * restart to ensure that the queue is run again after completion of the +- * request and zones being unlocked. + */ + static void dd_finish_request(struct request *rq) + { +@@ -942,21 +792,8 @@ static void dd_finish_request(struct request *rq) + * called dd_insert_requests(). Skip requests that bypassed I/O + * scheduling. See also blk_mq_request_bypass_insert(). + */ +- if (!rq->elv.priv[0]) +- return; +- +- atomic_inc(&per_prio->stats.completed); +- +- if (blk_queue_is_zoned(q)) { +- unsigned long flags; +- +- spin_lock_irqsave(&dd->zone_lock, flags); +- blk_req_zone_write_unlock(rq); +- spin_unlock_irqrestore(&dd->zone_lock, flags); +- +- if (dd_has_write_work(rq->mq_hctx)) +- blk_mq_sched_mark_restart_hctx(rq->mq_hctx); +- } ++ if (rq->elv.priv[0]) ++ atomic_inc(&per_prio->stats.completed); + } + + static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) +@@ -1280,7 +1117,6 @@ static struct elevator_type mq_deadline = { + .elevator_attrs = deadline_attrs, + .elevator_name = "mq-deadline", + .elevator_alias = "deadline", +- .elevator_features = ELEVATOR_F_ZBD_SEQ_WRITE, + .elevator_owner = THIS_MODULE, + }; + MODULE_ALIAS("mq-deadline-iosched"); +-- +2.51.0 + diff --git a/queue-6.6/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch b/queue-6.6/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch new file mode 100644 index 0000000000..e42da310ca --- /dev/null +++ b/queue-6.6/block-mq-deadline-switch-back-to-a-single-dispatch-l.patch @@ -0,0 +1,227 @@ +From 220216b3c0fa5760e6f83e6ad8f76dde2e35d6ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 12:28:03 -0700 +Subject: block/mq-deadline: Switch back to a single dispatch list + +From: Bart Van Assche + +[ Upstream commit d60055cf52703a705b86fb25b9b7931ec7ee399c ] + +Commit c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +modified the behavior of request flag BLK_MQ_INSERT_AT_HEAD from +dispatching a request before other requests into dispatching a request +before other requests with the same I/O priority. This is not correct since +BLK_MQ_INSERT_AT_HEAD is used when requeuing requests and also when a flush +request is inserted. Both types of requests should be dispatched as soon +as possible. Hence, make the mq-deadline I/O scheduler again ignore the I/O +priority for BLK_MQ_INSERT_AT_HEAD requests. + +Cc: Damien Le Moal +Cc: Yu Kuai +Reported-by: chengkaitao +Closes: https://lore.kernel.org/linux-block/20251009155253.14611-1-pilgrimtao@gmail.com/ +Fixes: c807ab520fc3 ("block/mq-deadline: Add I/O priority support") +Signed-off-by: Bart Van Assche +Reviewed-by: Damien Le Moalv +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/mq-deadline.c | 107 +++++++++++++++++++------------------------- + 1 file changed, 47 insertions(+), 60 deletions(-) + +diff --git a/block/mq-deadline.c b/block/mq-deadline.c +index b62f534a389e3..437eaa8b09e68 100644 +--- a/block/mq-deadline.c ++++ b/block/mq-deadline.c +@@ -71,7 +71,6 @@ struct io_stats_per_prio { + * present on both sort_list[] and fifo_list[]. + */ + struct dd_per_prio { +- struct list_head dispatch; + struct rb_root sort_list[DD_DIR_COUNT]; + struct list_head fifo_list[DD_DIR_COUNT]; + /* Position of the most recently dispatched request. */ +@@ -84,6 +83,7 @@ struct deadline_data { + * run time data + */ + ++ struct list_head dispatch; + struct dd_per_prio per_prio[DD_PRIO_COUNT]; + + /* Data direction of latest dispatched request. */ +@@ -364,16 +364,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + + lockdep_assert_held(&dd->lock); + +- if (!list_empty(&per_prio->dispatch)) { +- rq = list_first_entry(&per_prio->dispatch, struct request, +- queuelist); +- if (started_after(dd, rq, latest_start)) +- return NULL; +- list_del_init(&rq->queuelist); +- data_dir = rq_data_dir(rq); +- goto done; +- } +- + /* + * batches are currently reads XOR writes + */ +@@ -453,7 +443,6 @@ static struct request *__dd_dispatch_request(struct deadline_data *dd, + */ + dd->batching++; + deadline_move_request(dd, per_prio, rq); +-done: + return dd_start_request(dd, data_dir, rq); + } + +@@ -501,6 +490,14 @@ static struct request *dd_dispatch_request(struct blk_mq_hw_ctx *hctx) + enum dd_prio prio; + + spin_lock(&dd->lock); ++ ++ if (!list_empty(&dd->dispatch)) { ++ rq = list_first_entry(&dd->dispatch, struct request, queuelist); ++ list_del_init(&rq->queuelist); ++ dd_start_request(dd, rq_data_dir(rq), rq); ++ goto unlock; ++ } ++ + rq = dd_dispatch_prio_aged_requests(dd, now); + if (rq) + goto unlock; +@@ -619,10 +616,10 @@ static int dd_init_sched(struct request_queue *q, struct elevator_type *e) + + eq->elevator_data = dd; + ++ INIT_LIST_HEAD(&dd->dispatch); + for (prio = 0; prio <= DD_PRIO_MAX; prio++) { + struct dd_per_prio *per_prio = &dd->per_prio[prio]; + +- INIT_LIST_HEAD(&per_prio->dispatch); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_READ]); + INIT_LIST_HEAD(&per_prio->fifo_list[DD_WRITE]); + per_prio->sort_list[DD_READ] = RB_ROOT; +@@ -730,7 +727,7 @@ static void dd_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, + trace_block_rq_insert(rq); + + if (flags & BLK_MQ_INSERT_AT_HEAD) { +- list_add(&rq->queuelist, &per_prio->dispatch); ++ list_add(&rq->queuelist, &dd->dispatch); + rq->fifo_time = jiffies; + } else { + struct list_head *insert_before; +@@ -804,8 +801,7 @@ static void dd_finish_request(struct request *rq) + + static bool dd_has_work_for_prio(struct dd_per_prio *per_prio) + { +- return !list_empty_careful(&per_prio->dispatch) || +- !list_empty_careful(&per_prio->fifo_list[DD_READ]) || ++ return !list_empty_careful(&per_prio->fifo_list[DD_READ]) || + !list_empty_careful(&per_prio->fifo_list[DD_WRITE]); + } + +@@ -814,6 +810,9 @@ static bool dd_has_work(struct blk_mq_hw_ctx *hctx) + struct deadline_data *dd = hctx->queue->elevator->elevator_data; + enum dd_prio prio; + ++ if (!list_empty_careful(&dd->dispatch)) ++ return true; ++ + for (prio = 0; prio <= DD_PRIO_MAX; prio++) + if (dd_has_work_for_prio(&dd->per_prio[prio])) + return true; +@@ -1022,49 +1021,39 @@ static int dd_owned_by_driver_show(void *data, struct seq_file *m) + return 0; + } + +-#define DEADLINE_DISPATCH_ATTR(prio) \ +-static void *deadline_dispatch##prio##_start(struct seq_file *m, \ +- loff_t *pos) \ +- __acquires(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- spin_lock(&dd->lock); \ +- return seq_list_start(&per_prio->dispatch, *pos); \ +-} \ +- \ +-static void *deadline_dispatch##prio##_next(struct seq_file *m, \ +- void *v, loff_t *pos) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- struct dd_per_prio *per_prio = &dd->per_prio[prio]; \ +- \ +- return seq_list_next(v, &per_prio->dispatch, pos); \ +-} \ +- \ +-static void deadline_dispatch##prio##_stop(struct seq_file *m, void *v) \ +- __releases(&dd->lock) \ +-{ \ +- struct request_queue *q = m->private; \ +- struct deadline_data *dd = q->elevator->elevator_data; \ +- \ +- spin_unlock(&dd->lock); \ +-} \ +- \ +-static const struct seq_operations deadline_dispatch##prio##_seq_ops = { \ +- .start = deadline_dispatch##prio##_start, \ +- .next = deadline_dispatch##prio##_next, \ +- .stop = deadline_dispatch##prio##_stop, \ +- .show = blk_mq_debugfs_rq_show, \ ++static void *deadline_dispatch_start(struct seq_file *m, loff_t *pos) ++ __acquires(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_lock(&dd->lock); ++ return seq_list_start(&dd->dispatch, *pos); + } + +-DEADLINE_DISPATCH_ATTR(0); +-DEADLINE_DISPATCH_ATTR(1); +-DEADLINE_DISPATCH_ATTR(2); +-#undef DEADLINE_DISPATCH_ATTR ++static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ return seq_list_next(v, &dd->dispatch, pos); ++} ++ ++static void deadline_dispatch_stop(struct seq_file *m, void *v) ++ __releases(&dd->lock) ++{ ++ struct request_queue *q = m->private; ++ struct deadline_data *dd = q->elevator->elevator_data; ++ ++ spin_unlock(&dd->lock); ++} ++ ++static const struct seq_operations deadline_dispatch_seq_ops = { ++ .start = deadline_dispatch_start, ++ .next = deadline_dispatch_next, ++ .stop = deadline_dispatch_stop, ++ .show = blk_mq_debugfs_rq_show, ++}; + + #define DEADLINE_QUEUE_DDIR_ATTRS(name) \ + {#name "_fifo_list", 0400, \ +@@ -1087,9 +1076,7 @@ static const struct blk_mq_debugfs_attr deadline_queue_debugfs_attrs[] = { + {"batching", 0400, deadline_batching_show}, + {"starved", 0400, deadline_starved_show}, + {"async_depth", 0400, dd_async_depth_show}, +- {"dispatch0", 0400, .seq_ops = &deadline_dispatch0_seq_ops}, +- {"dispatch1", 0400, .seq_ops = &deadline_dispatch1_seq_ops}, +- {"dispatch2", 0400, .seq_ops = &deadline_dispatch2_seq_ops}, ++ {"dispatch", 0400, .seq_ops = &deadline_dispatch_seq_ops}, + {"owned_by_driver", 0400, dd_owned_by_driver_show}, + {"queued", 0400, dd_queued_show}, + {}, +-- +2.51.0 + diff --git a/queue-6.6/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch b/queue-6.6/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch new file mode 100644 index 0000000000..73430745c7 --- /dev/null +++ b/queue-6.6/bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch @@ -0,0 +1,69 @@ +From 92e6e621a1031a6378a7447850e6900dd73b35a5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 15:23:30 -0800 +Subject: bpf: Check skb->transport_header is set in bpf_skb_check_mtu + +From: Martin KaFai Lau + +[ Upstream commit d946f3c98328171fa50ddb908593cf833587f725 ] + +The bpf_skb_check_mtu helper needs to use skb->transport_header when +the BPF_MTU_CHK_SEGS flag is used: + + bpf_skb_check_mtu(skb, ifindex, &mtu_len, 0, BPF_MTU_CHK_SEGS) + +The transport_header is not always set. There is a WARN_ON_ONCE +report when CONFIG_DEBUG_NET is enabled + skb->gso_size is set + +bpf_prog_test_run is used: + +WARNING: CPU: 1 PID: 2216 at ./include/linux/skbuff.h:3071 + skb_gso_validate_network_len + bpf_skb_check_mtu + bpf_prog_3920e25740a41171_tc_chk_segs_flag # A test in the next patch + bpf_test_run + bpf_prog_test_run_skb + +For a normal ingress skb (not test_run), skb_reset_transport_header +is performed but there is plan to avoid setting it as described in +commit 2170a1f09148 ("net: no longer reset transport_header in __netif_receive_skb_core()"). + +This patch fixes the bpf helper by checking +skb_transport_header_was_set(). The check is done just before +skb->transport_header is used, to avoid breaking the existing bpf prog. +The WARN_ON_ONCE is limited to bpf_prog_test_run, so targeting bpf-next. + +Fixes: 34b2021cc616 ("bpf: Add BPF-helper for MTU checking") +Cc: Jesper Dangaard Brouer +Reported-by: Kaiyan Mei +Reported-by: Yinhao Hu +Signed-off-by: Martin KaFai Lau +Link: https://lore.kernel.org/r/20251112232331.1566074-1-martin.lau@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/core/filter.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/net/core/filter.c b/net/core/filter.c +index 0564ee6ac8731..da1a617b7db94 100644 +--- a/net/core/filter.c ++++ b/net/core/filter.c +@@ -6295,9 +6295,12 @@ BPF_CALL_5(bpf_skb_check_mtu, struct sk_buff *, skb, + */ + if (skb_is_gso(skb)) { + ret = BPF_MTU_CHK_RET_SUCCESS; +- if (flags & BPF_MTU_CHK_SEGS && +- !skb_gso_validate_network_len(skb, mtu)) +- ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ if (flags & BPF_MTU_CHK_SEGS) { ++ if (!skb_transport_header_was_set(skb)) ++ return -EINVAL; ++ if (!skb_gso_validate_network_len(skb, mtu)) ++ ret = BPF_MTU_CHK_RET_SEGS_TOOBIG; ++ } + } + out: + *mtu_len = mtu; +-- +2.51.0 + diff --git a/queue-6.6/bpf-fix-invalid-prog-stats-access-when-update_effect.patch b/queue-6.6/bpf-fix-invalid-prog-stats-access-when-update_effect.patch new file mode 100644 index 0000000000..080bf4d32c --- /dev/null +++ b/queue-6.6/bpf-fix-invalid-prog-stats-access-when-update_effect.patch @@ -0,0 +1,91 @@ +From 8c1950187a0242cfa2f04ec112d7d939fc0e8dfb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:23:43 +0000 +Subject: bpf: Fix invalid prog->stats access when update_effective_progs fails + +From: Pu Lehui + +[ Upstream commit 7dc211c1159d991db609bdf4b0fb9033c04adcbc ] + +Syzkaller triggers an invalid memory access issue following fault +injection in update_effective_progs. The issue can be described as +follows: + +__cgroup_bpf_detach + update_effective_progs + compute_effective_progs + bpf_prog_array_alloc <-- fault inject + purge_effective_progs + /* change to dummy_bpf_prog */ + array->items[index] = &dummy_bpf_prog.prog + +---softirq start--- +__do_softirq + ... + __cgroup_bpf_run_filter_skb + __bpf_prog_run_save_cb + bpf_prog_run + stats = this_cpu_ptr(prog->stats) + /* invalid memory access */ + flags = u64_stats_update_begin_irqsave(&stats->syncp) +---softirq end--- + + static_branch_dec(&cgroup_bpf_enabled_key[atype]) + +The reason is that fault injection caused update_effective_progs to fail +and then changed the original prog into dummy_bpf_prog.prog in +purge_effective_progs. Then a softirq came, and accessing the members of +dummy_bpf_prog.prog in the softirq triggers invalid mem access. + +To fix it, skip updating stats when stats is NULL. + +Fixes: 492ecee892c2 ("bpf: enable program stats") +Signed-off-by: Pu Lehui +Link: https://lore.kernel.org/r/20251115102343.2200727-1-pulehui@huaweicloud.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 12 +++++++----- + kernel/bpf/syscall.c | 3 +++ + 2 files changed, 10 insertions(+), 5 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index f9fb83be935d4..30fe140d48888 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -605,11 +605,13 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + + duration = sched_clock() - start; +- stats = this_cpu_ptr(prog->stats); +- flags = u64_stats_update_begin_irqsave(&stats->syncp); +- u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, duration); +- u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ if (likely(prog->stats)) { ++ stats = this_cpu_ptr(prog->stats); ++ flags = u64_stats_update_begin_irqsave(&stats->syncp); ++ u64_stats_inc(&stats->cnt); ++ u64_stats_add(&stats->nsecs, duration); ++ u64_stats_update_end_irqrestore(&stats->syncp, flags); ++ } + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); + } +diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c +index 98f3f206d112e..63cf5a221081b 100644 +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -2224,6 +2224,9 @@ void notrace bpf_prog_inc_misses_counter(struct bpf_prog *prog) + struct bpf_prog_stats *stats; + unsigned int flags; + ++ if (unlikely(!prog->stats)) ++ return; ++ + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->misses); +-- +2.51.0 + diff --git a/queue-6.6/bpf-free-special-fields-when-update-lru_-percpu_hash.patch b/queue-6.6/bpf-free-special-fields-when-update-lru_-percpu_hash.patch new file mode 100644 index 0000000000..f6a26c5a58 --- /dev/null +++ b/queue-6.6/bpf-free-special-fields-when-update-lru_-percpu_hash.patch @@ -0,0 +1,58 @@ +From ec049abad9f543522aef0fe0507beccba15f40f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 23:14:06 +0800 +Subject: bpf: Free special fields when update [lru_,]percpu_hash maps + +From: Leon Hwang + +[ Upstream commit 6af6e49a76c9af7d42eb923703e7648cb2bf401a ] + +As [lru_,]percpu_hash maps support BPF_KPTR_{REF,PERCPU}, missing +calls to 'bpf_obj_free_fields()' in 'pcpu_copy_value()' could cause the +memory referenced by BPF_KPTR_{REF,PERCPU} fields to be held until the +map gets freed. + +Fix this by calling 'bpf_obj_free_fields()' after +'copy_map_value[,_long]()' in 'pcpu_copy_value()'. + +Fixes: 65334e64a493 ("bpf: Support kptrs in percpu hashmap and percpu LRU hashmap") +Signed-off-by: Leon Hwang +Acked-by: Yonghong Song +Link: https://lore.kernel.org/r/20251105151407.12723-2-leon.hwang@linux.dev +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/hashtab.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c +index 8a3eadf17f785..8bac6ae1204dc 100644 +--- a/kernel/bpf/hashtab.c ++++ b/kernel/bpf/hashtab.c +@@ -957,15 +957,21 @@ static void free_htab_elem(struct bpf_htab *htab, struct htab_elem *l) + static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr, + void *value, bool onallcpus) + { ++ void *ptr; ++ + if (!onallcpus) { + /* copy true value_size bytes */ +- copy_map_value(&htab->map, this_cpu_ptr(pptr), value); ++ ptr = this_cpu_ptr(pptr); ++ copy_map_value(&htab->map, ptr, value); ++ bpf_obj_free_fields(htab->map.record, ptr); + } else { + u32 size = round_up(htab->map.value_size, 8); + int off = 0, cpu; + + for_each_possible_cpu(cpu) { +- copy_map_value_long(&htab->map, per_cpu_ptr(pptr, cpu), value + off); ++ ptr = per_cpu_ptr(pptr, cpu); ++ copy_map_value_long(&htab->map, ptr, value + off); ++ bpf_obj_free_fields(htab->map.record, ptr); + off += size; + } + } +-- +2.51.0 + diff --git a/queue-6.6/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch b/queue-6.6/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch new file mode 100644 index 0000000000..76d9592b5c --- /dev/null +++ b/queue-6.6/bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch @@ -0,0 +1,40 @@ +From 24094a61d9093109febeff0433f9ac314d26f919 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:07:05 +0800 +Subject: bpf: Handle return value of ftrace_set_filter_ip in register_fentry + +From: Menglong Dong + +[ Upstream commit fea3f5e83c5cd80a76d97343023a2f2e6bd862bf ] + +The error that returned by ftrace_set_filter_ip() in register_fentry() is +not handled properly. Just fix it. + +Fixes: 00963a2e75a8 ("bpf: Support bpf_trampoline on functions with IPMODIFY (e.g. livepatch)") +Signed-off-by: Menglong Dong +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251110120705.1553694-1-dongml2@chinatelecom.cn +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/trampoline.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index b6024fc903490..f8a58b4130701 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -216,7 +216,9 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr) + } + + if (tr->func.ftrace_managed) { +- ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ ret = ftrace_set_filter_ip(tr->fops, (unsigned long)ip, 0, 1); ++ if (ret) ++ return ret; + ret = register_ftrace_direct(tr->fops, (long)new_addr); + } else { + ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr); +-- +2.51.0 + diff --git a/queue-6.6/bpf-improve-program-stats-run-time-calculation.patch b/queue-6.6/bpf-improve-program-stats-run-time-calculation.patch new file mode 100644 index 0000000000..9cc556c59d --- /dev/null +++ b/queue-6.6/bpf-improve-program-stats-run-time-calculation.patch @@ -0,0 +1,85 @@ +From 2ada9c8840d7ae65185512d1a24973df7181a1a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 1 Apr 2024 21:40:10 -0600 +Subject: bpf: Improve program stats run-time calculation + +From: Jose Fernandez + +[ Upstream commit ce09cbdd988887662546a1175bcfdfc6c8fdd150 ] + +This patch improves the run-time calculation for program stats by +capturing the duration as soon as possible after the program returns. + +Previously, the duration included u64_stats_t operations. While the +instrumentation overhead is part of the total time spent when stats are +enabled, distinguishing between the program's native execution time and +the time spent due to instrumentation is crucial for accurate +performance analysis. + +By making this change, the patch facilitates more precise optimization +of BPF programs, enabling users to understand their performance in +environments without stats enabled. + +I used a virtualized environment to measure the run-time over one minute +for a basic raw_tracepoint/sys_enter program, which just increments a +local counter. Although the virtualization introduced some performance +degradation that could affect the results, I observed approximately a +16% decrease in average run-time reported by stats with this change +(310 -> 260 nsec). + +Signed-off-by: Jose Fernandez +Signed-off-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20240402034010.25060-1-josef@netflix.com +Stable-dep-of: 7dc211c1159d ("bpf: Fix invalid prog->stats access when update_effective_progs fails") +Signed-off-by: Sasha Levin +--- + include/linux/filter.h | 6 ++++-- + kernel/bpf/trampoline.c | 3 ++- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/include/linux/filter.h b/include/linux/filter.h +index ad5a3d68b5552..f9fb83be935d4 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -599,14 +599,16 @@ static __always_inline u32 __bpf_prog_run(const struct bpf_prog *prog, + cant_migrate(); + if (static_branch_unlikely(&bpf_stats_enabled_key)) { + struct bpf_prog_stats *stats; +- u64 start = sched_clock(); ++ u64 duration, start = sched_clock(); + unsigned long flags; + + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); ++ ++ duration = sched_clock() - start; + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } else { + ret = dfunc(ctx, prog->insnsi, prog->bpf_func); +diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c +index f8a58b4130701..e48791442acc5 100644 +--- a/kernel/bpf/trampoline.c ++++ b/kernel/bpf/trampoline.c +@@ -870,12 +870,13 @@ static void notrace update_prog_stats(struct bpf_prog *prog, + * Hence check that 'start' is valid. + */ + start > NO_START_TIME) { ++ u64 duration = sched_clock() - start; + unsigned long flags; + + stats = this_cpu_ptr(prog->stats); + flags = u64_stats_update_begin_irqsave(&stats->syncp); + u64_stats_inc(&stats->cnt); +- u64_stats_add(&stats->nsecs, sched_clock() - start); ++ u64_stats_add(&stats->nsecs, duration); + u64_stats_update_end_irqrestore(&stats->syncp, flags); + } + } +-- +2.51.0 + diff --git a/queue-6.6/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch b/queue-6.6/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch new file mode 100644 index 0000000000..83c033b6bc --- /dev/null +++ b/queue-6.6/btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch @@ -0,0 +1,41 @@ +From 50156636c8eeae803071d631f338d4bac5ff1116 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 12:52:45 +0000 +Subject: btrfs: fix leaf leak in an error path in btrfs_del_items() + +From: Filipe Manana + +[ Upstream commit e7dd1182fcedee7c6097c9f49eba8de94a4364e3 ] + +If the call to btrfs_del_leaf() fails we return without decrementing the +extra ref we took on the leaf, therefore leaking it. Fix this by ensuring +we drop the ref count before returning the error. + +Fixes: 751a27615dda ("btrfs: do not BUG_ON() on tree mod log failures at btrfs_del_ptr()") +Reviewed-by: Qu Wenruo +Signed-off-by: Filipe Manana +Reviewed-by: David Sterba +Signed-off-by: David Sterba +Signed-off-by: Sasha Levin +--- + fs/btrfs/ctree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c +index 31b1b448efc2e..a26c6e9d562d6 100644 +--- a/fs/btrfs/ctree.c ++++ b/fs/btrfs/ctree.c +@@ -4743,9 +4743,9 @@ int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, + if (btrfs_header_nritems(leaf) == 0) { + path->slots[1] = slot; + ret = btrfs_del_leaf(trans, root, path, leaf); ++ free_extent_buffer(leaf); + if (ret < 0) + return ret; +- free_extent_buffer(leaf); + ret = 0; + } else { + /* if we're still in the path, make sure +-- +2.51.0 + diff --git a/queue-6.6/clk-keystone-fix-compile-testing.patch b/queue-6.6/clk-keystone-fix-compile-testing.patch new file mode 100644 index 0000000000..96c62f73c8 --- /dev/null +++ b/queue-6.6/clk-keystone-fix-compile-testing.patch @@ -0,0 +1,41 @@ +From c3c21b64495ca461d79b2cb96d8df2d858d4ce5b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:53:25 +0100 +Subject: clk: keystone: fix compile testing + +From: Johan Hovold + +[ Upstream commit b276445e98fe28609688fb85b89a81b803910e63 ] + +Some keystone clock drivers can be selected when COMPILE_TEST is +enabled but since commit b745c0794e2f ("clk: keystone: Add sci-clk +driver support") they are never actually built. + +Enable compile testing by allowing the build system to process the +keystone drivers. + +Fixes: b745c0794e2f ("clk: keystone: Add sci-clk driver support") +Signed-off-by: Johan Hovold +Signed-off-by: Stephen Boyd +Signed-off-by: Sasha Levin +--- + drivers/clk/Makefile | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 18969cbd4bb1e..8d572021977fd 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -95,8 +95,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/ + obj-y += imgtec/ + obj-y += imx/ + obj-y += ingenic/ +-obj-$(CONFIG_ARCH_K3) += keystone/ +-obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ ++obj-y += keystone/ + obj-y += mediatek/ + obj-$(CONFIG_ARCH_MESON) += meson/ + obj-y += microchip/ +-- +2.51.0 + diff --git a/queue-6.6/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch b/queue-6.6/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch new file mode 100644 index 0000000000..ab90ce33a9 --- /dev/null +++ b/queue-6.6/clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch @@ -0,0 +1,53 @@ +From 2a67152c22cc8d188ee889697dd61783da4e6160 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Oct 2025 20:08:54 +0200 +Subject: clk: qcom: camcc-sm6350: Fix PLL config of PLL2 + +From: Luca Weiss + +[ Upstream commit ab0e13141d679fdffdd3463a272c5c1b10be1794 ] + +The 'Agera' PLLs (with clk_agera_pll_configure) do not take some of the +parameters that are provided in the vendor driver. Instead the upstream +configuration should provide the final user_ctl value that is written to +the USER_CTL register. + +Fix the config so that the PLL is configured correctly, and fixes +CAMCC_MCLK* being stuck off. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Suggested-by: Taniya Das +Signed-off-by: Luca Weiss +Reviewed-by: Abel Vesa +Reviewed-by: Taniya Das +Link: https://lore.kernel.org/r/20251021-agera-pll-fixups-v1-1-8c1d8aff4afc@fairphone.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index 79131e1699b81..83cee6994d160 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -144,15 +144,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = { + static const struct alpha_pll_config camcc_pll2_config = { + .l = 0x64, + .alpha = 0x0, +- .post_div_val = 0x3 << 8, +- .post_div_mask = 0x3 << 8, +- .aux_output_mask = BIT(1), +- .main_output_mask = BIT(0), +- .early_output_mask = BIT(3), + .config_ctl_val = 0x20000800, + .config_ctl_hi_val = 0x400003d2, + .test_ctl_val = 0x04000400, + .test_ctl_hi_val = 0x00004000, ++ .user_ctl_val = 0x0000030b, + }; + + static struct clk_alpha_pll camcc_pll2 = { +-- +2.51.0 + diff --git a/queue-6.6/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch b/queue-6.6/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch new file mode 100644 index 0000000000..c2773cd379 --- /dev/null +++ b/queue-6.6/clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch @@ -0,0 +1,89 @@ +From 27879024983e4a3a5fe3dfa9d14bc4d9dfa8c228 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 22 Oct 2025 02:44:46 +0300 +Subject: clk: qcom: camcc-sm6350: Specify Titan GDSC power domain as a parent + to other + +From: Vladimir Zapolskiy + +[ Upstream commit a76ce61d7225934b0a52c8172a8cd944002a8c6f ] + +When a consumer turns on/off a power domain dependent on another power +domain in hardware, the parent power domain shall be turned on/off by +the power domain provider as well, and to get it the power domain hardware +hierarchy shall be described in the CAMCC driver. + +Establish the power domain hierarchy with a Titan GDSC set as a parent of +all other GDSC power domains provided by the SM6350 camera clock controller +to enforce a correct sequence of enabling and disabling power domains by +the consumers, this fixes the CAMCC as a supplier of power domains to CAMSS +IP and its driver. + +Fixes: 80f5451d9a7c ("clk: qcom: Add camera clock controller driver for SM6350") +Reviewed-by: Konrad Dybcio +Reviewed-by: Imran Shaik +Reviewed-by: Bryan O'Donoghue +Signed-off-by: Vladimir Zapolskiy +Link: https://lore.kernel.org/r/20251021234450.2271279-3-vladimir.zapolskiy@linaro.org +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/clk/qcom/camcc-sm6350.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/clk/qcom/camcc-sm6350.c b/drivers/clk/qcom/camcc-sm6350.c +index eca36bd3ba5c9..79131e1699b81 100644 +--- a/drivers/clk/qcom/camcc-sm6350.c ++++ b/drivers/clk/qcom/camcc-sm6350.c +@@ -1692,6 +1692,8 @@ static struct clk_branch camcc_sys_tmr_clk = { + }, + }; + ++static struct gdsc titan_top_gdsc; ++ + static struct gdsc bps_gdsc = { + .gdscr = 0x6004, + .en_rest_wait_val = 0x2, +@@ -1701,6 +1703,7 @@ static struct gdsc bps_gdsc = { + .name = "bps_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1713,6 +1716,7 @@ static struct gdsc ipe_0_gdsc = { + .name = "ipe_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + .flags = VOTABLE, + }; + +@@ -1725,6 +1729,7 @@ static struct gdsc ife_0_gdsc = { + .name = "ife_0_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_1_gdsc = { +@@ -1736,6 +1741,7 @@ static struct gdsc ife_1_gdsc = { + .name = "ife_1_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc ife_2_gdsc = { +@@ -1747,6 +1753,7 @@ static struct gdsc ife_2_gdsc = { + .name = "ife_2_gdsc", + }, + .pwrsts = PWRSTS_OFF_ON, ++ .parent = &titan_top_gdsc.pd, + }; + + static struct gdsc titan_top_gdsc = { +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch b/queue-6.6/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch new file mode 100644 index 0000000000..2a8faffd39 --- /dev/null +++ b/queue-6.6/clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch @@ -0,0 +1,58 @@ +From df25d7cb2cc98a5e511a50e9cec8c09ced75273d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 05:04:43 +0200 +Subject: clk: renesas: cpg-mssr: Add missing 1ms delay into reset toggle + callback + +From: Marek Vasut + +[ Upstream commit 62abfd7bedc2b3d86d4209a4146f9d2b5ae21fab ] + +R-Car V4H Reference Manual R19UH0186EJ0130 Rev.1.30 Apr. 21, 2025 page +583 Figure 9.3.1(a) Software Reset flow (A) as well as flow (B) / (C) +indicate after reset has been asserted by writing a matching reset bit +into register SRCR, it is mandatory to wait 1ms. + +This 1ms delay is documented on R-Car V4H and V4M, it is currently +unclear whether S4 is affected as well. This patch does apply the extra +delay on R-Car S4 as well. + +Fix the reset driver to respect the additional delay when toggling +resets. Drivers which use separate reset_control_(de)assert() must +assure matching delay in their driver code. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250918030552.331389-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index cb80d1bf6c7c6..55ac571c73884 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -612,8 +612,15 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + /* Reset module */ + writel(bitmask, priv->base + priv->reset_regs[reg]); + +- /* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */ +- udelay(35); ++ /* ++ * On R-Car Gen4, delay after SRCR has been written is 1ms. ++ * On older SoCs, delay after SRCR has been written is 35us ++ * (one cycle of the RCLK clock @ ca. 32 kHz). ++ */ ++ if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) ++ usleep_range(1000, 2000); ++ else ++ usleep_range(35, 1000); + + /* Release module from reset state */ + writel(bitmask, priv->base + priv->reset_clear_regs[reg]); +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch b/queue-6.6/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch new file mode 100644 index 0000000000..b03da6b92b --- /dev/null +++ b/queue-6.6/clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch @@ -0,0 +1,124 @@ +From 21b7573df1581a3eeeed4f4e51e56392c137c832 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 18:20:38 +0200 +Subject: clk: renesas: cpg-mssr: Read back reset registers to assure values + latched + +From: Marek Vasut + +[ Upstream commit b91401af6c00ffab003698bfabd4c166df30748b ] + +On R-Car V4H, the PCIEC controller DBI read would generate an SError in +case the controller reset is released by writing SRSTCLR register first, +and immediately afterward reading some PCIEC controller DBI register. +The issue triggers in rcar_gen4_pcie_additional_common_init() on +dw_pcie_readl_dbi(dw, PCIE_PORT_LANE_SKEW), which on V4H is the first +read after reset_control_deassert(dw->core_rsts[DW_PCIE_PWR_RST].rstc). + +The reset controller which contains the SRSTCLR register and the PCIEC +controller which contains the DBI register share the same root access +bus, but the bus then splits into separate segments before reaching each +IP. Even if the SRSTCLR write access was posted on the bus before the +DBI read access, it seems the DBI read access may reach the PCIEC +controller before the SRSTCLR write completed, and trigger the SError. + +Mitigate the issue by adding a dummy SRSTCLR read, which assures the +SRSTCLR write completes fully and is latched into the reset controller, +before the PCIEC DBI read access can occur. + +Fixes: 0ab55cf18341 ("clk: renesas: cpg-mssr: Add support for R-Car V4H") +Reviewed-by: Wolfram Sang +Tested-by: Geert Uytterhoeven +Signed-off-by: Marek Vasut +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20250922162113.113223-1-marek.vasut+renesas@mailbox.org +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 46 ++++++++++++-------------- + 1 file changed, 21 insertions(+), 25 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index c66b5e7359284..0f558d94750f1 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -597,18 +597,32 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev, + + #define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev) + +-static int cpg_mssr_reset(struct reset_controller_dev *rcdev, +- unsigned long id) ++static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev, ++ const char *func, bool set, unsigned long id) + { + struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + unsigned int reg = id / 32; + unsigned int bit = id % 32; ++ const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg]; + u32 bitmask = BIT(bit); + +- dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); ++ if (func) ++ dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit); ++ ++ writel(bitmask, priv->pub.base0 + off); ++ readl(priv->pub.base0 + off); ++ barrier_data(priv->pub.base0 + off); ++ ++ return 0; ++} ++ ++static int cpg_mssr_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); + + /* Reset module */ +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); ++ cpg_mssr_reset_operate(rcdev, "reset", true, id); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -621,36 +635,18 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- +- return 0; ++ return cpg_mssr_reset_operate(rcdev, NULL, false, id); + } + + static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "assert", true, id); + } + + static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + unsigned long id) + { +- struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev); +- unsigned int reg = id / 32; +- unsigned int bit = id % 32; +- u32 bitmask = BIT(bit); +- +- dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); +- +- writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); +- return 0; ++ return cpg_mssr_reset_operate(rcdev, "deassert", false, id); + } + + static int cpg_mssr_status(struct reset_controller_dev *rcdev, +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch b/queue-6.6/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch new file mode 100644 index 0000000000..86d57aa128 --- /dev/null +++ b/queue-6.6/clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch @@ -0,0 +1,554 @@ +From 51e33a3da9e9dffc99bb2d01235f93bc242bf3d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 15 May 2025 16:18:19 +0200 +Subject: clk: renesas: Pass sub struct of cpg_mssr_priv to cpg_clk_register + +From: Thierry Bultel + +[ Upstream commit 3d37ca1482c36975255f29911a529f84f1bc34a9 ] + +In a subsequent patch, the registration callback will need more parameters +from cpg_mssr_priv (like another base address with clock controllers +with double register block, and also, notifiers and rmw_lock). +Instead of adding more parameters, move the needed parameters to a public +sub-struct. +Instead moving clks to this structure, which would have implied to add +an allocation (and cleanup) for it, keep the way the allocation is done +and just have a copy of the pointer in the public structure. + +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Thierry Bultel +Link: https://lore.kernel.org/20250515141828.43444-5-thierry.bultel.yh@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r7s9210-cpg-mssr.c | 7 +- + drivers/clk/renesas/r8a77970-cpg-mssr.c | 8 +- + drivers/clk/renesas/rcar-gen2-cpg.c | 5 +- + drivers/clk/renesas/rcar-gen2-cpg.h | 3 +- + drivers/clk/renesas/rcar-gen3-cpg.c | 6 +- + drivers/clk/renesas/rcar-gen3-cpg.h | 3 +- + drivers/clk/renesas/rcar-gen4-cpg.c | 6 +- + drivers/clk/renesas/rcar-gen4-cpg.h | 3 +- + drivers/clk/renesas/renesas-cpg-mssr.c | 98 ++++++++++++------------- + drivers/clk/renesas/renesas-cpg-mssr.h | 20 ++++- + 10 files changed, 88 insertions(+), 71 deletions(-) + +diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c +index a85227c248f31..733244687daa8 100644 +--- a/drivers/clk/renesas/r7s9210-cpg-mssr.c ++++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c +@@ -159,12 +159,13 @@ static void __init r7s9210_update_clk_table(struct clk *extal_clk, + + static struct clk * __init rza2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { +- struct clk *parent; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + unsigned int mult = 1; + unsigned int div = 1; ++ struct clk *parent; + + parent = clks[core->parent]; + if (IS_ERR(parent)) +diff --git a/drivers/clk/renesas/r8a77970-cpg-mssr.c b/drivers/clk/renesas/r8a77970-cpg-mssr.c +index 7e90e94c4b688..0c568a113c3fd 100644 +--- a/drivers/clk/renesas/r8a77970-cpg-mssr.c ++++ b/drivers/clk/renesas/r8a77970-cpg-mssr.c +@@ -222,10 +222,11 @@ static int __init r8a77970_cpg_mssr_init(struct device *dev) + + static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { + const struct clk_div_table *table; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int shift; + +@@ -239,8 +240,7 @@ static struct clk * __init r8a77970_cpg_clk_register(struct device *dev, + shift = 4; + break; + default: +- return rcar_gen3_cpg_clk_register(dev, core, info, clks, base, +- notifiers); ++ return rcar_gen3_cpg_clk_register(dev, core, info, pub); + } + + parent = clks[core->parent]; +diff --git a/drivers/clk/renesas/rcar-gen2-cpg.c b/drivers/clk/renesas/rcar-gen2-cpg.c +index edae874fa2b63..1a59a71eede21 100644 +--- a/drivers/clk/renesas/rcar-gen2-cpg.c ++++ b/drivers/clk/renesas/rcar-gen2-cpg.c +@@ -274,10 +274,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { + + struct clk * __init rcar_gen2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { + const struct clk_div_table *table = NULL; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + const char *parent_name; + unsigned int mult = 1; +diff --git a/drivers/clk/renesas/rcar-gen2-cpg.h b/drivers/clk/renesas/rcar-gen2-cpg.h +index bdcd4a38d48d0..3d4b127fdeaf4 100644 +--- a/drivers/clk/renesas/rcar-gen2-cpg.h ++++ b/drivers/clk/renesas/rcar-gen2-cpg.h +@@ -32,8 +32,7 @@ struct rcar_gen2_cpg_pll_config { + + struct clk *rcar_gen2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen2_cpg_init(const struct rcar_gen2_cpg_pll_config *config, + unsigned int pll0_div, u32 mode); + +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.c b/drivers/clk/renesas/rcar-gen3-cpg.c +index d0129a6509411..47d52e2c996eb 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.c ++++ b/drivers/clk/renesas/rcar-gen3-cpg.c +@@ -346,9 +346,11 @@ static const struct soc_device_attribute cpg_quirks_match[] __initconst = { + + struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { ++ struct raw_notifier_head *notifiers = &pub->notifiers; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; +diff --git a/drivers/clk/renesas/rcar-gen3-cpg.h b/drivers/clk/renesas/rcar-gen3-cpg.h +index bfdc649bdf12c..d15a5d1df71c7 100644 +--- a/drivers/clk/renesas/rcar-gen3-cpg.h ++++ b/drivers/clk/renesas/rcar-gen3-cpg.h +@@ -81,8 +81,7 @@ struct rcar_gen3_cpg_pll_config { + + struct clk *rcar_gen3_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen3_cpg_init(const struct rcar_gen3_cpg_pll_config *config, + unsigned int clk_extalr, u32 mode); + +diff --git a/drivers/clk/renesas/rcar-gen4-cpg.c b/drivers/clk/renesas/rcar-gen4-cpg.c +index c68d8b9870541..b7bc3e6860c79 100644 +--- a/drivers/clk/renesas/rcar-gen4-cpg.c ++++ b/drivers/clk/renesas/rcar-gen4-cpg.c +@@ -330,9 +330,11 @@ static const struct clk_div_table cpg_rpcsrc_div_table[] = { + + struct clk * __init rcar_gen4_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers) ++ struct cpg_mssr_pub *pub) + { ++ struct raw_notifier_head *notifiers = &pub->notifiers; ++ void __iomem *base = pub->base0; ++ struct clk **clks = pub->clks; + const struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; +diff --git a/drivers/clk/renesas/rcar-gen4-cpg.h b/drivers/clk/renesas/rcar-gen4-cpg.h +index 006537e29e4eb..f479c30a30e88 100644 +--- a/drivers/clk/renesas/rcar-gen4-cpg.h ++++ b/drivers/clk/renesas/rcar-gen4-cpg.h +@@ -72,8 +72,7 @@ struct rcar_gen4_cpg_pll_config { + + struct clk *rcar_gen4_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + int rcar_gen4_cpg_init(const struct rcar_gen4_cpg_pll_config *config, + unsigned int clk_extalr, u32 mode); + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 908bb9517cc1b..c66b5e7359284 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -127,16 +127,14 @@ static const u16 srstclr_for_gen4[] = { + * struct cpg_mssr_priv - Clock Pulse Generator / Module Standby + * and Software Reset Private Data + * ++ * @pub: Data passed to clock registration callback + * @rcdev: Optional reset controller entity + * @dev: CPG/MSSR device +- * @base: CPG/MSSR register block base address + * @reg_layout: CPG/MSSR register layout +- * @rmw_lock: protects RMW register accesses + * @np: Device node in DT for this CPG/MSSR module + * @num_core_clks: Number of Core Clocks in clks[] + * @num_mod_clks: Number of Module Clocks in clks[] + * @last_dt_core_clk: ID of the last Core Clock exported to DT +- * @notifiers: Notifier chain to save/restore clock state for system resume + * @status_regs: Pointer to status registers array + * @control_regs: Pointer to control registers array + * @reset_regs: Pointer to reset registers array +@@ -146,20 +144,18 @@ static const u16 srstclr_for_gen4[] = { + * @clks: Array containing all Core and Module Clocks + */ + struct cpg_mssr_priv { ++ struct cpg_mssr_pub pub; + #ifdef CONFIG_RESET_CONTROLLER + struct reset_controller_dev rcdev; + #endif + struct device *dev; +- void __iomem *base; + enum clk_reg_layout reg_layout; +- spinlock_t rmw_lock; + struct device_node *np; + + unsigned int num_core_clks; + unsigned int num_mod_clks; + unsigned int last_dt_core_clk; + +- struct raw_notifier_head notifiers; + const u16 *status_regs; + const u16 *control_regs; + const u16 *reset_regs; +@@ -202,38 +198,39 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, + str_on_off(enable)); +- spin_lock_irqsave(&priv->rmw_lock, flags); ++ spin_lock_irqsave(&priv->pub.rmw_lock, flags); + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +- value = readb(priv->base + priv->control_regs[reg]); ++ value = readb(priv->pub.base0 + priv->control_regs[reg]); + if (enable) + value &= ~bitmask; + else + value |= bitmask; +- writeb(value, priv->base + priv->control_regs[reg]); ++ writeb(value, priv->pub.base0 + priv->control_regs[reg]); + + /* dummy read to ensure write has completed */ +- readb(priv->base + priv->control_regs[reg]); +- barrier_data(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]); ++ barrier_data(priv->pub.base0 + priv->control_regs[reg]); ++ + } else { +- value = readl(priv->base + priv->control_regs[reg]); ++ value = readl(priv->pub.base0 + priv->control_regs[reg]); + if (enable) + value &= ~bitmask; + else + value |= bitmask; +- writel(value, priv->base + priv->control_regs[reg]); ++ writel(value, priv->pub.base0 + priv->control_regs[reg]); + } + +- spin_unlock_irqrestore(&priv->rmw_lock, flags); ++ spin_unlock_irqrestore(&priv->pub.rmw_lock, flags); + + if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A) + return 0; + +- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], ++ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], + value, !(value & bitmask), 0, 10); + if (error) + dev_err(dev, "Failed to enable SMSTP %p[%d]\n", +- priv->base + priv->control_regs[reg], bit); ++ priv->pub.base0 + priv->control_regs[reg], bit); + + return error; + } +@@ -252,12 +249,13 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) + { + struct mstp_clock *clock = to_mstp_clock(hw); + struct cpg_mssr_priv *priv = clock->priv; ++ unsigned int reg = clock->index / 32; + u32 value; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) +- value = readb(priv->base + priv->control_regs[clock->index / 32]); ++ value = readb(priv->pub.base0 + priv->control_regs[reg]); + else +- value = readl(priv->base + priv->status_regs[clock->index / 32]); ++ value = readl(priv->pub.base0 + priv->status_regs[reg]); + + return !(value & BIT(clock->index % 32)); + } +@@ -349,7 +347,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + case CLK_TYPE_DIV6P1: + case CLK_TYPE_DIV6_RO: + WARN_DEBUG(core->parent >= priv->num_core_clks); +- parent = priv->clks[core->parent]; ++ parent = priv->pub.clks[core->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; +@@ -359,12 +357,12 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + + if (core->type == CLK_TYPE_DIV6_RO) + /* Multiply with the DIV6 register value */ +- div *= (readl(priv->base + core->offset) & 0x3f) + 1; ++ div *= (readl(priv->pub.base0 + core->offset) & 0x3f) + 1; + + if (core->type == CLK_TYPE_DIV6P1) { + clk = cpg_div6_register(core->name, 1, &parent_name, +- priv->base + core->offset, +- &priv->notifiers); ++ priv->pub.base0 + core->offset, ++ &priv->pub.notifiers); + } else { + clk = clk_register_fixed_factor(NULL, core->name, + parent_name, 0, +@@ -380,8 +378,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + default: + if (info->cpg_clk_register) + clk = info->cpg_clk_register(dev, core, info, +- priv->clks, priv->base, +- &priv->notifiers); ++ &priv->pub); + else + dev_err(dev, "%s has unsupported core clock type %u\n", + core->name, core->type); +@@ -392,7 +389,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, + goto fail; + + dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk)); +- priv->clks[id] = clk; ++ priv->pub.clks[id] = clk; + return; + + fail: +@@ -415,14 +412,14 @@ static void __init cpg_mssr_register_mod_clk(const struct mssr_mod_clk *mod, + WARN_DEBUG(id < priv->num_core_clks); + WARN_DEBUG(id >= priv->num_core_clks + priv->num_mod_clks); + WARN_DEBUG(mod->parent >= priv->num_core_clks + priv->num_mod_clks); +- WARN_DEBUG(PTR_ERR(priv->clks[id]) != -ENOENT); ++ WARN_DEBUG(PTR_ERR(priv->pub.clks[id]) != -ENOENT); + + if (!mod->name) { + /* Skip NULLified clock */ + return; + } + +- parent = priv->clks[mod->parent]; ++ parent = priv->pub.clks[mod->parent]; + if (IS_ERR(parent)) { + clk = parent; + goto fail; +@@ -611,7 +608,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + dev_dbg(priv->dev, "reset %u%02u\n", reg, bit); + + /* Reset module */ +- writel(bitmask, priv->base + priv->reset_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + + /* + * On R-Car Gen4, delay after SRCR has been written is 1ms. +@@ -624,7 +621,7 @@ static int cpg_mssr_reset(struct reset_controller_dev *rcdev, + usleep_range(35, 1000); + + /* Release module from reset state */ +- writel(bitmask, priv->base + priv->reset_clear_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); + + return 0; + } +@@ -638,7 +635,7 @@ static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id) + + dev_dbg(priv->dev, "assert %u%02u\n", reg, bit); + +- writel(bitmask, priv->base + priv->reset_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]); + return 0; + } + +@@ -652,7 +649,7 @@ static int cpg_mssr_deassert(struct reset_controller_dev *rcdev, + + dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit); + +- writel(bitmask, priv->base + priv->reset_clear_regs[reg]); ++ writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]); + return 0; + } + +@@ -664,7 +661,7 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev, + unsigned int bit = id % 32; + u32 bitmask = BIT(bit); + +- return !!(readl(priv->base + priv->reset_regs[reg]) & bitmask); ++ return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask); + } + + static const struct reset_control_ops cpg_mssr_reset_ops = { +@@ -885,12 +882,12 @@ static int cpg_mssr_suspend_noirq(struct device *dev) + if (priv->smstpcr_saved[reg].mask) + priv->smstpcr_saved[reg].val = + priv->reg_layout == CLK_REG_LAYOUT_RZ_A ? +- readb(priv->base + priv->control_regs[reg]) : +- readl(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]) : ++ readl(priv->pub.base0 + priv->control_regs[reg]); + } + + /* Save core clocks */ +- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_SUSPEND, NULL); ++ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_SUSPEND, NULL); + + return 0; + } +@@ -907,7 +904,7 @@ static int cpg_mssr_resume_noirq(struct device *dev) + return 0; + + /* Restore core clocks */ +- raw_notifier_call_chain(&priv->notifiers, PM_EVENT_RESUME, NULL); ++ raw_notifier_call_chain(&priv->pub.notifiers, PM_EVENT_RESUME, NULL); + + /* Restore module clocks */ + for (reg = 0; reg < ARRAY_SIZE(priv->smstpcr_saved); reg++) { +@@ -916,29 +913,29 @@ static int cpg_mssr_resume_noirq(struct device *dev) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) +- oldval = readb(priv->base + priv->control_regs[reg]); ++ oldval = readb(priv->pub.base0 + priv->control_regs[reg]); + else +- oldval = readl(priv->base + priv->control_regs[reg]); ++ oldval = readl(priv->pub.base0 + priv->control_regs[reg]); + newval = oldval & ~mask; + newval |= priv->smstpcr_saved[reg].val & mask; + if (newval == oldval) + continue; + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +- writeb(newval, priv->base + priv->control_regs[reg]); ++ writeb(newval, priv->pub.base0 + priv->control_regs[reg]); + /* dummy read to ensure write has completed */ +- readb(priv->base + priv->control_regs[reg]); +- barrier_data(priv->base + priv->control_regs[reg]); ++ readb(priv->pub.base0 + priv->control_regs[reg]); ++ barrier_data(priv->pub.base0 + priv->control_regs[reg]); + continue; + } else +- writel(newval, priv->base + priv->control_regs[reg]); ++ writel(newval, priv->pub.base0 + priv->control_regs[reg]); + + /* Wait until enabled clocks are really enabled */ + mask &= ~priv->smstpcr_saved[reg].val; + if (!mask) + continue; + +- error = readl_poll_timeout_atomic(priv->base + priv->status_regs[reg], ++ error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg], + oldval, !(oldval & mask), 0, 10); + if (error) + dev_warn(dev, "Failed to enable SMSTP%u[0x%x]\n", reg, +@@ -976,12 +973,13 @@ static int __init cpg_mssr_common_init(struct device *dev, + if (!priv) + return -ENOMEM; + ++ priv->pub.clks = priv->clks; + priv->np = np; + priv->dev = dev; +- spin_lock_init(&priv->rmw_lock); ++ spin_lock_init(&priv->pub.rmw_lock); + +- priv->base = of_iomap(np, 0); +- if (!priv->base) { ++ priv->pub.base0 = of_iomap(np, 0); ++ if (!priv->pub.base0) { + error = -ENOMEM; + goto out_err; + } +@@ -989,7 +987,7 @@ static int __init cpg_mssr_common_init(struct device *dev, + priv->num_core_clks = info->num_total_core_clks; + priv->num_mod_clks = info->num_hw_mod_clks; + priv->last_dt_core_clk = info->last_dt_core_clk; +- RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); ++ RAW_INIT_NOTIFIER_HEAD(&priv->pub.notifiers); + priv->reg_layout = info->reg_layout; + if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) { + priv->status_regs = mstpsr; +@@ -1009,7 +1007,7 @@ static int __init cpg_mssr_common_init(struct device *dev, + } + + for (i = 0; i < nclks; i++) +- priv->clks[i] = ERR_PTR(-ENOENT); ++ priv->pub.clks[i] = ERR_PTR(-ENOENT); + + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) +@@ -1020,8 +1018,8 @@ static int __init cpg_mssr_common_init(struct device *dev, + return 0; + + out_err: +- if (priv->base) +- iounmap(priv->base); ++ if (priv->pub.base0) ++ iounmap(priv->pub.base0); + kfree(priv); + + return error; +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h +index 80c5b462924ac..0a7b0b328d822 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.h ++++ b/drivers/clk/renesas/renesas-cpg-mssr.h +@@ -8,6 +8,8 @@ + #ifndef __CLK_RENESAS_CPG_MSSR_H__ + #define __CLK_RENESAS_CPG_MSSR_H__ + ++#include ++ + /* + * Definitions of CPG Core Clocks + * +@@ -29,6 +31,21 @@ struct cpg_core_clk { + unsigned int offset; + }; + ++/** ++ * struct cpg_mssr_pub - data shared with device-specific clk registration code ++ * ++ * @base0: CPG/MSSR register block base0 address ++ * @notifiers: Notifier chain to save/restore clock state for system resume ++ * @rmw_lock: protects RMW register accesses ++ * @clks: pointer to clocks ++ */ ++struct cpg_mssr_pub { ++ void __iomem *base0; ++ struct raw_notifier_head notifiers; ++ spinlock_t rmw_lock; ++ struct clk **clks; ++}; ++ + enum clk_types { + /* Generic */ + CLK_TYPE_IN, /* External Clock Input */ +@@ -153,8 +170,7 @@ struct cpg_mssr_info { + struct clk *(*cpg_clk_register)(struct device *dev, + const struct cpg_core_clk *core, + const struct cpg_mssr_info *info, +- struct clk **clks, void __iomem *base, +- struct raw_notifier_head *notifiers); ++ struct cpg_mssr_pub *pub); + }; + + extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch b/queue-6.6/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch new file mode 100644 index 0000000000..a7b45013b8 --- /dev/null +++ b/queue-6.6/clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch @@ -0,0 +1,48 @@ +From 09f689b36f8f36d2f8464c6eac2d1e4de3375b1f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 14:16:03 +0800 +Subject: clk: renesas: r9a06g032: Fix memory leak in error path + +From: Haotian Zhang + +[ Upstream commit f8def051bbcf8677f64701e9699bf6d11e2780cd ] + +The current code uses of_iomap() to map registers but never calls +iounmap() on any error path after the mapping. This causes a memory +leak when probe fails after successful ioremap, for example when +of_clk_add_provider() or r9a06g032_add_clk_domain() fails. + +Replace of_iomap() with devm_of_iomap() to automatically unmap the +region on probe failure. Update the error check accordingly to use +IS_ERR() and PTR_ERR() since devm_of_iomap() returns ERR_PTR on error. + +Fixes: 4c3d88526eba ("clk: renesas: Renesas R9A06G032 clock driver") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Link: https://patch.msgid.link/20251030061603.1954-1-vulab@iscas.ac.cn +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/r9a06g032-clocks.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/r9a06g032-clocks.c b/drivers/clk/renesas/r9a06g032-clocks.c +index 55db63c7041a6..cdc820b7e6ea9 100644 +--- a/drivers/clk/renesas/r9a06g032-clocks.c ++++ b/drivers/clk/renesas/r9a06g032-clocks.c +@@ -1316,9 +1316,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev) + if (IS_ERR(mclk)) + return PTR_ERR(mclk); + +- clocks->reg = of_iomap(np, 0); +- if (WARN_ON(!clocks->reg)) +- return -ENOMEM; ++ clocks->reg = devm_of_iomap(dev, np, 0, NULL); ++ if (IS_ERR(clocks->reg)) ++ return PTR_ERR(clocks->reg); + + r9a06g032_init_h2mode(clocks); + +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-remove-critical-area.patch b/queue-6.6/clk-renesas-rzg2l-remove-critical-area.patch new file mode 100644 index 0000000000..f873b9b980 --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-remove-critical-area.patch @@ -0,0 +1,56 @@ +From 54b7c718c862fdc19f2c8244df85ff904162a9b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 29 Sep 2023 08:38:53 +0300 +Subject: clk: renesas: rzg2l: Remove critical area + +From: Claudiu Beznea + +[ Upstream commit 5f710e3bc5987373737470f98798bbd49134a2e0 ] + +The spinlock in rzg2l_mod_clock_endisable() is intended to protect +RMW-accesses to the hardware register. There is no need to protect +instructions that set temporary variables which will be written +afterwards to a hardware register. With this only one write to one +clock register is executed thus locking/unlocking rmw_lock is removed. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230929053915.1530607-7-claudiu.beznea@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 0b3b6097b33a0..b7fa4c7eb8016 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -978,7 +978,6 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + struct rzg2l_cpg_priv *priv = clock->priv; + unsigned int reg = clock->off; + struct device *dev = priv->dev; +- unsigned long flags; + u32 bitmask = BIT(clock->bit); + u32 value; + int error; +@@ -990,14 +989,12 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + + dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, + enable ? "ON" : "OFF"); +- spin_lock_irqsave(&priv->rmw_lock, flags); + + value = bitmask << 16; + if (enable) + value |= bitmask; +- writel(value, priv->base + CLK_ON_R(reg)); + +- spin_unlock_irqrestore(&priv->rmw_lock, flags); ++ writel(value, priv->base + CLK_ON_R(reg)); + + if (!enable) + return 0; +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-simplify-the-logic-in-rzg2l_mod_cl.patch b/queue-6.6/clk-renesas-rzg2l-simplify-the-logic-in-rzg2l_mod_cl.patch new file mode 100644 index 0000000000..01eac6a576 --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-simplify-the-logic-in-rzg2l_mod_cl.patch @@ -0,0 +1,44 @@ +From d49d9c3dc75db209972f10f418b3707d36011f9f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 07:51:31 +0300 +Subject: clk: renesas: rzg2l: Simplify the logic in + rzg2l_mod_clock_endisable() + +From: Claudiu Beznea + +[ Upstream commit becf4a771a12b52dc5b3d2b089598d5603f3bbec ] + +The bitmask << 16 is anyway set on both branches of if thus move it +before the if and set the lower bits of registers only in case clock is +enabled. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230912045157.177966-12-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index 77eefb6ee4538..0b3b6097b33a0 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -992,10 +992,9 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + enable ? "ON" : "OFF"); + spin_lock_irqsave(&priv->rmw_lock, flags); + ++ value = bitmask << 16; + if (enable) +- value = (bitmask << 16) | bitmask; +- else +- value = bitmask << 16; ++ value |= bitmask; + writel(value, priv->base + CLK_ON_R(reg)); + + spin_unlock_irqrestore(&priv->rmw_lock, flags); +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-rzg2l-use-x-format-specifier-to-print-cl.patch b/queue-6.6/clk-renesas-rzg2l-use-x-format-specifier-to-print-cl.patch new file mode 100644 index 0000000000..d0a46cabbd --- /dev/null +++ b/queue-6.6/clk-renesas-rzg2l-use-x-format-specifier-to-print-cl.patch @@ -0,0 +1,39 @@ +From 125db4283a7ee4b2e665126be03e5c3c5435ac02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 10 Oct 2023 16:26:56 +0300 +Subject: clk: renesas: rzg2l: Use %x format specifier to print CLK_ON_R() + +From: Claudiu Beznea + +[ Upstream commit fd627207aaa782c1fd4224076b56a03a1059f516 ] + +Use the %x format specifier to print CLK_ON_R(). This makes debugging +easier as the value printed will be hexadecimal like in the hardware +manual. Along with it add "0x" in front of the printed value. + +Signed-off-by: Claudiu Beznea +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20231010132701.1658737-2-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Geert Uytterhoeven +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/rzg2l-cpg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index b7fa4c7eb8016..ab71f9cd250b0 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -987,7 +987,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + return 0; + } + +- dev_dbg(dev, "CLK_ON %u/%pC %s\n", CLK_ON_R(reg), hw->clk, ++ dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, + enable ? "ON" : "OFF"); + + value = bitmask << 16; +-- +2.51.0 + diff --git a/queue-6.6/clk-renesas-use-str_on_off-helper.patch b/queue-6.6/clk-renesas-use-str_on_off-helper.patch new file mode 100644 index 0000000000..b73e949c39 --- /dev/null +++ b/queue-6.6/clk-renesas-use-str_on_off-helper.patch @@ -0,0 +1,67 @@ +From e3d7d93ddd21974754b33f60b283c682f410eac3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 28 Apr 2025 13:45:55 +0200 +Subject: clk: renesas: Use str_on_off() helper + +From: Geert Uytterhoeven + +[ Upstream commit aff664cc8cbc5c28e5aa57dc4201c34497f3c871 ] + +Use the str_on_off() helper instead of open-coding the same operation. +Note that this does change the case of the flags, which doesn't matter +much for debug messages. + +Signed-off-by: Geert Uytterhoeven +Link: https://lore.kernel.org/622f8554dcb815c8fc73511a1a118c1724570fa9.1745840497.git.geert+renesas@glider.be +Stable-dep-of: b91401af6c00 ("clk: renesas: cpg-mssr: Read back reset registers to assure values latched") +Signed-off-by: Sasha Levin +--- + drivers/clk/renesas/renesas-cpg-mssr.c | 3 ++- + drivers/clk/renesas/rzg2l-cpg.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c +index 55ac571c73884..908bb9517cc1b 100644 +--- a/drivers/clk/renesas/renesas-cpg-mssr.c ++++ b/drivers/clk/renesas/renesas-cpg-mssr.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + #include + +@@ -200,7 +201,7 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) + int error; + + dev_dbg(dev, "MSTP %u%02u/%pC %s\n", reg, bit, hw->clk, +- enable ? "ON" : "OFF"); ++ str_on_off(enable)); + spin_lock_irqsave(&priv->rmw_lock, flags); + + if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A) { +diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c +index ab71f9cd250b0..4bba49215c710 100644 +--- a/drivers/clk/renesas/rzg2l-cpg.c ++++ b/drivers/clk/renesas/rzg2l-cpg.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #include + + #include +@@ -988,7 +989,7 @@ static int rzg2l_mod_clock_endisable(struct clk_hw *hw, bool enable) + } + + dev_dbg(dev, "CLK_ON 0x%x/%pC %s\n", CLK_ON_R(reg), hw->clk, +- enable ? "ON" : "OFF"); ++ str_on_off(enable)); + + value = bitmask << 16; + if (enable) +-- +2.51.0 + diff --git a/queue-6.6/coresight-etm4x-add-context-synchronization-before-e.patch b/queue-6.6/coresight-etm4x-add-context-synchronization-before-e.patch new file mode 100644 index 0000000000..e8f0f491f1 --- /dev/null +++ b/queue-6.6/coresight-etm4x-add-context-synchronization-before-e.patch @@ -0,0 +1,87 @@ +From 6e093171642f1922395b8607f4d39fbf7e388e28 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:39 +0000 +Subject: coresight: etm4x: Add context synchronization before enabling trace + +From: Leo Yan + +[ Upstream commit 64eb04ae545294e105ad91714dc3167a0b660731 ] + +According to the software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), a +Context synchronization event is required before enabling the trace +unit. + +An ISB is added to meet this requirement, particularly for guarding the +operations in the flow: + + etm4x_allow_trace() + `> kvm_tracing_set_el1_configuration() + `> write_sysreg_s(trfcr_while_in_guest, SYS_TRFCR_EL12) + +Improved the barrier comments to provide more accurate information. + +Fixes: 1ab3bb9df5e3 ("coresight: etm4x: Add necessary synchronization for sysreg access") +Reviewed-by: Mike Leach +Reviewed-by: Yeoreun Yun +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-5-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 27 ++++++++++++++++--- + 1 file changed, 23 insertions(+), 4 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index a53816f24cd94..c5928f63475a0 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -436,10 +436,24 @@ static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); + + etm4x_allow_trace(drvdata); ++ ++ /* ++ * According to software usage PKLXF in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee the trace unit ++ * will observe the new values of the System registers. ++ */ ++ if (!csa->io_mem) ++ isb(); ++ + /* Enable the trace unit */ + etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); + +- /* Synchronize the register updates for sysreg access */ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using system ++ * instructions to progrom the trace unit") of ARM IHI 0064H.b, the ++ * self-hosted trace analyzer must perform a Context synchronization ++ * event between writing to the TRCPRGCTLR and reading the TRCSTATR. ++ */ + if (!csa->io_mem) + isb(); + +@@ -916,11 +930,16 @@ static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + */ + etm4x_prohibit_trace(drvdata); + /* +- * Make sure everything completes before disabling, as recommended +- * by section 7.3.77 ("TRCVICTLR, ViewInst Main Control Register, +- * SSTATUS") of ARM IHI 0064D ++ * Prevent being speculative at the point of disabling the trace unit, ++ * as recommended by section 7.3.77 ("TRCVICTLR, ViewInst Main Control ++ * Register, SSTATUS") of ARM IHI 0064D + */ + dsb(sy); ++ /* ++ * According to software usage VKHHY in Arm ARM (ARM DDI 0487 L.a), ++ * execute a Context synchronization event to guarantee no new ++ * program-flow trace is generated. ++ */ + isb(); + /* Trace synchronization barrier, is a nop if not supported */ + tsb_csync(); +-- +2.51.0 + diff --git a/queue-6.6/coresight-etm4x-correct-polling-idle-bit.patch b/queue-6.6/coresight-etm4x-correct-polling-idle-bit.patch new file mode 100644 index 0000000000..b05aab8e32 --- /dev/null +++ b/queue-6.6/coresight-etm4x-correct-polling-idle-bit.patch @@ -0,0 +1,43 @@ +From 67a29000218dab5fca38179020cb2691c1395ff7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 18:58:38 +0000 +Subject: coresight: etm4x: Correct polling IDLE bit + +From: Leo Yan + +[ Upstream commit 4dc4e22f9536341255f5de6047977a80ff47eaef ] + +Since commit 4ff6039ffb79 ("coresight-etm4x: add isb() before reading +the TRCSTATR"), the code has incorrectly been polling the PMSTABLE bit +instead of the IDLE bit. + +This commit corrects the typo. + +Fixes: 4ff6039ffb79 ("coresight-etm4x: add isb() before reading the TRCSTATR") +Reviewed-by: Yeoreum Yun +Reviewed-by: Mike Leach +Tested-by: James Clark +Signed-off-by: Leo Yan +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20251111-arm_coresight_power_management_fix-v6-4-f55553b6c8b3@arm.com +Signed-off-by: Sasha Levin +--- + drivers/hwtracing/coresight/coresight-etm4x-core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index e4d8d446ea4d3..cc35175abd504 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -1805,7 +1805,7 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata) + state->trcpdcr = etm4x_read32(csa, TRCPDCR); + + /* wait for TRCSTATR.IDLE to go up */ +- if (etm4x_wait_status(csa, TRCSTATR_PMSTABLE_BIT, 1)) { ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 1)) { + dev_err(etm_dev, + "timeout while waiting for Idle Trace Status\n"); + etm4_os_unlock(drvdata); +-- +2.51.0 + diff --git a/queue-6.6/coresight-etm4x-extract-the-trace-unit-controlling.patch b/queue-6.6/coresight-etm4x-extract-the-trace-unit-controlling.patch new file mode 100644 index 0000000000..30c2c8405f --- /dev/null +++ b/queue-6.6/coresight-etm4x-extract-the-trace-unit-controlling.patch @@ -0,0 +1,171 @@ +From 3528e745e787a46a3013cc9616bb2955dcd6e561 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Apr 2025 19:07:02 +0100 +Subject: coresight: etm4x: Extract the trace unit controlling + +From: Leo Yan + +[ Upstream commit 40f682ae5086366d51e29e66eb8a344501245d0d ] + +The trace unit is controlled in the ETM hardware enabling and disabling. +The sequential changes for support AUX pause and resume will reuse the +same operations. + +Extract the operations in the etm4_{enable|disable}_trace_unit() +functions. A minor improvement in etm4_enable_trace_unit() is for +returning the timeout error to callers. + +Signed-off-by: Leo Yan +Reviewed-by: Mike Leach +Reviewed-by: James Clark +Signed-off-by: Suzuki K Poulose +Link: https://lore.kernel.org/r/20250401180708.385396-2-leo.yan@arm.com +Stable-dep-of: 64eb04ae5452 ("coresight: etm4x: Add context synchronization before enabling trace") +Signed-off-by: Sasha Levin +--- + .../coresight/coresight-etm4x-core.c | 103 +++++++++++------- + 1 file changed, 62 insertions(+), 41 deletions(-) + +diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c +index cc35175abd504..a53816f24cd94 100644 +--- a/drivers/hwtracing/coresight/coresight-etm4x-core.c ++++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c +@@ -422,6 +422,44 @@ static int etm4x_wait_status(struct csdev_access *csa, int pos, int val) + return coresight_timeout(csa, TRCSTATR, pos, val); + } + ++static int etm4_enable_trace_unit(struct etmv4_drvdata *drvdata) ++{ ++ struct coresight_device *csdev = drvdata->csdev; ++ struct device *etm_dev = &csdev->dev; ++ struct csdev_access *csa = &csdev->access; ++ ++ /* ++ * ETE mandates that the TRCRSR is written to before ++ * enabling it. ++ */ ++ if (etm4x_is_ete(drvdata)) ++ etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); ++ ++ etm4x_allow_trace(drvdata); ++ /* Enable the trace unit */ ++ etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); ++ ++ /* Synchronize the register updates for sysreg access */ ++ if (!csa->io_mem) ++ isb(); ++ ++ /* wait for TRCSTATR.IDLE to go back down to '0' */ ++ if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) { ++ dev_err(etm_dev, ++ "timeout while waiting for Idle Trace Status\n"); ++ return -ETIME; ++ } ++ ++ /* ++ * As recommended by section 4.3.7 ("Synchronization when using the ++ * memory-mapped interface") of ARM IHI 0064D ++ */ ++ dsb(sy); ++ isb(); ++ ++ return 0; ++} ++ + static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + { + int i, rc; +@@ -531,33 +569,7 @@ static int etm4_enable_hw(struct etmv4_drvdata *drvdata) + etm4x_relaxed_write32(csa, trcpdcr | TRCPDCR_PU, TRCPDCR); + } + +- /* +- * ETE mandates that the TRCRSR is written to before +- * enabling it. +- */ +- if (etm4x_is_ete(drvdata)) +- etm4x_relaxed_write32(csa, TRCRSR_TA, TRCRSR); +- +- etm4x_allow_trace(drvdata); +- /* Enable the trace unit */ +- etm4x_relaxed_write32(csa, 1, TRCPRGCTLR); +- +- /* Synchronize the register updates for sysreg access */ +- if (!csa->io_mem) +- isb(); +- +- /* wait for TRCSTATR.IDLE to go back down to '0' */ +- if (etm4x_wait_status(csa, TRCSTATR_IDLE_BIT, 0)) +- dev_err(etm_dev, +- "timeout while waiting for Idle Trace Status\n"); +- +- /* +- * As recommended by section 4.3.7 ("Synchronization when using the +- * memory-mapped interface") of ARM IHI 0064D +- */ +- dsb(sy); +- isb(); +- ++ rc = etm4_enable_trace_unit(drvdata); + done: + etm4_cs_lock(drvdata, csa); + +@@ -886,25 +898,12 @@ static int etm4_enable(struct coresight_device *csdev, struct perf_event *event, + return ret; + } + +-static void etm4_disable_hw(void *info) ++static void etm4_disable_trace_unit(struct etmv4_drvdata *drvdata) + { + u32 control; +- struct etmv4_drvdata *drvdata = info; +- struct etmv4_config *config = &drvdata->config; + struct coresight_device *csdev = drvdata->csdev; + struct device *etm_dev = &csdev->dev; + struct csdev_access *csa = &csdev->access; +- int i; +- +- etm4_cs_unlock(drvdata, csa); +- etm4_disable_arch_specific(drvdata); +- +- if (!drvdata->skip_power_up) { +- /* power can be removed from the trace unit now */ +- control = etm4x_relaxed_read32(csa, TRCPDCR); +- control &= ~TRCPDCR_PU; +- etm4x_relaxed_write32(csa, control, TRCPDCR); +- } + + control = etm4x_relaxed_read32(csa, TRCPRGCTLR); + +@@ -945,6 +944,28 @@ static void etm4_disable_hw(void *info) + * of ARM IHI 0064H.b. + */ + isb(); ++} ++ ++static void etm4_disable_hw(void *info) ++{ ++ u32 control; ++ struct etmv4_drvdata *drvdata = info; ++ struct etmv4_config *config = &drvdata->config; ++ struct coresight_device *csdev = drvdata->csdev; ++ struct csdev_access *csa = &csdev->access; ++ int i; ++ ++ etm4_cs_unlock(drvdata, csa); ++ etm4_disable_arch_specific(drvdata); ++ ++ if (!drvdata->skip_power_up) { ++ /* power can be removed from the trace unit now */ ++ control = etm4x_relaxed_read32(csa, TRCPDCR); ++ control &= ~TRCPDCR_PU; ++ etm4x_relaxed_write32(csa, control, TRCPDCR); ++ } ++ ++ etm4_disable_trace_unit(drvdata); + + /* read the status of the single shot comparators */ + for (i = 0; i < drvdata->nr_ss_cmp; i++) { +-- +2.51.0 + diff --git a/queue-6.6/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch b/queue-6.6/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch new file mode 100644 index 0000000000..dff5e07e48 --- /dev/null +++ b/queue-6.6/cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch @@ -0,0 +1,44 @@ +From e1998788dde0079825dde537cf38bd609c0c1781 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 13:11:45 +0530 +Subject: cpufreq/amd-pstate: Call cppc_set_auto_sel() only for online CPUs + +From: Gautham R. Shenoy + +[ Upstream commit bb31fef0d03ed17d587b40e3458786be408fb9df ] + +amd_pstate_change_mode_without_dvr_change() calls cppc_set_auto_sel() +for all the present CPUs. + +However, this callpath eventually calls cppc_set_reg_val() which +accesses the per-cpu cpc_desc_ptr object. This object is initialized +only for online CPUs via acpi_soft_cpu_online() --> +__acpi_processor_start() --> acpi_cppc_processor_probe(). + +Hence, restrict calling cppc_set_auto_sel() to only the online CPUs. + +Fixes: 3ca7bc818d8c ("cpufreq: amd-pstate: Add guided mode control support via sysfs") +Suggested-by: Mario Limonciello (AMD) (kernel.org) +Signed-off-by: Gautham R. Shenoy +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Sasha Levin +--- + drivers/cpufreq/amd-pstate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/cpufreq/amd-pstate.c b/drivers/cpufreq/amd-pstate.c +index a64baa97e3583..7e7fa04188cf6 100644 +--- a/drivers/cpufreq/amd-pstate.c ++++ b/drivers/cpufreq/amd-pstate.c +@@ -1100,7 +1100,7 @@ static int amd_pstate_change_mode_without_dvr_change(int mode) + if (boot_cpu_has(X86_FEATURE_CPPC) || cppc_state == AMD_PSTATE_ACTIVE) + return 0; + +- for_each_present_cpu(cpu) { ++ for_each_online_cpu(cpu) { + cppc_set_auto_sel(cpu, (cppc_state == AMD_PSTATE_PASSIVE) ? 0 : 1); + } + +-- +2.51.0 + diff --git a/queue-6.6/cpuset-treat-cpusets-in-attaching-as-populated.patch b/queue-6.6/cpuset-treat-cpusets-in-attaching-as-populated.patch new file mode 100644 index 0000000000..6dc0d5edfd --- /dev/null +++ b/queue-6.6/cpuset-treat-cpusets-in-attaching-as-populated.patch @@ -0,0 +1,115 @@ +From 7040fe143617b1500429054178075514dbcee57d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 02:08:47 +0000 +Subject: cpuset: Treat cpusets in attaching as populated + +From: Chen Ridong + +[ Upstream commit b1bcaed1e39a9e0dfbe324a15d2ca4253deda316 ] + +Currently, the check for whether a partition is populated does not +account for tasks in the cpuset of attaching. This is a corner case +that can leave a task stuck in a partition with no effective CPUs. + +The race condition occurs as follows: + +cpu0 cpu1 + //cpuset A with cpu N +migrate task p to A +cpuset_can_attach +// with effective cpus +// check ok + +// cpuset_mutex is not held // clear cpuset.cpus.exclusive + // making effective cpus empty + update_exclusive_cpumask + // tasks_nocpu_error check ok + // empty effective cpus, partition valid +cpuset_attach +... +// task p stays in A, with non-effective cpus. + +To fix this issue, this patch introduces cs_is_populated, which considers +tasks in the attaching cpuset. This new helper is used in validate_change +and partition_is_populated. + +Fixes: e2d59900d936 ("cgroup/cpuset: Allow no-task partition to have empty cpuset.cpus.effective") +Signed-off-by: Chen Ridong +Reviewed-by: Waiman Long +Signed-off-by: Tejun Heo +Signed-off-by: Sasha Levin +--- + kernel/cgroup/cpuset.c | 35 +++++++++++++++++++++++++++-------- + 1 file changed, 27 insertions(+), 8 deletions(-) + +diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c +index eadb028916c81..f61dde0497f39 100644 +--- a/kernel/cgroup/cpuset.c ++++ b/kernel/cgroup/cpuset.c +@@ -453,6 +453,15 @@ static inline bool is_in_v2_mode(void) + (cpuset_cgrp_subsys.root->flags & CGRP_ROOT_CPUSET_V2_MODE); + } + ++static inline bool cpuset_is_populated(struct cpuset *cs) ++{ ++ lockdep_assert_held(&cpuset_mutex); ++ ++ /* Cpusets in the process of attaching should be considered as populated */ ++ return cgroup_is_populated(cs->css.cgroup) || ++ cs->attach_in_progress; ++} ++ + /** + * partition_is_populated - check if partition has tasks + * @cs: partition root to be checked +@@ -465,21 +474,31 @@ static inline bool is_in_v2_mode(void) + static inline bool partition_is_populated(struct cpuset *cs, + struct cpuset *excluded_child) + { +- struct cgroup_subsys_state *css; +- struct cpuset *child; ++ struct cpuset *cp; ++ struct cgroup_subsys_state *pos_css; + +- if (cs->css.cgroup->nr_populated_csets) ++ /* ++ * We cannot call cs_is_populated(cs) directly, as ++ * nr_populated_domain_children may include populated ++ * csets from descendants that are partitions. ++ */ ++ if (cs->css.cgroup->nr_populated_csets || ++ cs->attach_in_progress) + return true; + if (!excluded_child && !cs->nr_subparts_cpus) + return cgroup_is_populated(cs->css.cgroup); + + rcu_read_lock(); +- cpuset_for_each_child(child, css, cs) { +- if (child == excluded_child) ++ cpuset_for_each_descendant_pre(cp, pos_css, cs) { ++ if (cp == cs || cp == excluded_child) + continue; +- if (is_partition_valid(child)) ++ ++ if (is_partition_valid(cp)) { ++ pos_css = css_rightmost_descendant(pos_css); + continue; +- if (cgroup_is_populated(child->css.cgroup)) { ++ } ++ ++ if (cpuset_is_populated(cp)) { + rcu_read_unlock(); + return true; + } +@@ -751,7 +770,7 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) + * be changed to have empty cpus_allowed or mems_allowed. + */ + ret = -ENOSPC; +- if ((cgroup_is_populated(cur->css.cgroup) || cur->attach_in_progress)) { ++ if (cpuset_is_populated(cur)) { + if (!cpumask_empty(cur->cpus_allowed) && + cpumask_empty(trial->cpus_allowed)) + goto out; +-- +2.51.0 + diff --git a/queue-6.6/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch b/queue-6.6/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch new file mode 100644 index 0000000000..33e5f48d03 --- /dev/null +++ b/queue-6.6/crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch @@ -0,0 +1,63 @@ +From 9877b060097d8df0078ff8b19c88c3430ae2663e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 13:40:10 +0200 +Subject: crypto: asymmetric_keys - prevent overflow in + asymmetric_key_generate_id + +From: Thorsten Blum + +[ Upstream commit df0845cf447ae1556c3440b8b155de0926cbaa56 ] + +Use check_add_overflow() to guard against potential integer overflows +when adding the binary blob lengths and the size of an asymmetric_key_id +structure and return ERR_PTR(-EOVERFLOW) accordingly. This prevents a +possible buffer overflow when copying data from potentially malicious +X.509 certificate fields that can be arbitrarily large, such as ASN.1 +INTEGER serial numbers, issuer names, etc. + +Fixes: 7901c1a8effb ("KEYS: Implement binary asymmetric key ID handling") +Signed-off-by: Thorsten Blum +Reviewed-by: Lukas Wunner +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/asymmetric_keys/asymmetric_type.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c +index 43af5fa510c09..7859b0692b42b 100644 +--- a/crypto/asymmetric_keys/asymmetric_type.c ++++ b/crypto/asymmetric_keys/asymmetric_type.c +@@ -11,6 +11,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -151,12 +152,17 @@ struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1, + size_t len_2) + { + struct asymmetric_key_id *kid; +- +- kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2, +- GFP_KERNEL); ++ size_t kid_sz; ++ size_t len; ++ ++ if (check_add_overflow(len_1, len_2, &len)) ++ return ERR_PTR(-EOVERFLOW); ++ if (check_add_overflow(sizeof(struct asymmetric_key_id), len, &kid_sz)) ++ return ERR_PTR(-EOVERFLOW); ++ kid = kmalloc(kid_sz, GFP_KERNEL); + if (!kid) + return ERR_PTR(-ENOMEM); +- kid->len = len_1 + len_2; ++ kid->len = len; + memcpy(kid->data, val_1, len_1); + memcpy(kid->data + len_1, val_2, len_2); + return kid; +-- +2.51.0 + diff --git a/queue-6.6/crypto-authenc-correctly-pass-einprogress-back-up-to.patch b/queue-6.6/crypto-authenc-correctly-pass-einprogress-back-up-to.patch new file mode 100644 index 0000000000..419ac510be --- /dev/null +++ b/queue-6.6/crypto-authenc-correctly-pass-einprogress-back-up-to.patch @@ -0,0 +1,202 @@ +From 5da02a42af1584c03e8e9374feec794381b8bdb5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 18:20:17 +0800 +Subject: crypto: authenc - Correctly pass EINPROGRESS back up to the caller + +From: Herbert Xu + +[ Upstream commit 96feb73def02d175850daa0e7c2c90c876681b5c ] + +When authenc is invoked with MAY_BACKLOG, it needs to pass EINPROGRESS +notifications back up to the caller when the underlying algorithm +returns EBUSY synchronously. + +However, if the EBUSY comes from the second part of an authenc call, +i.e., it is asynchronous, both the EBUSY and the subsequent EINPROGRESS +notification must not be passed to the caller. + +Implement this by passing a mask to the function that starts the +second half of authenc and using it to determine whether EBUSY +and EINPROGRESS should be passed to the caller. + +This was a deficiency in the original implementation of authenc +because it was not expected to be used with MAY_BACKLOG. + +Reported-by: Ingo Franzki +Reported-by: Mikulas Patocka +Fixes: 180ce7e81030 ("crypto: authenc - Add EINPROGRESS check") +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + crypto/authenc.c | 75 ++++++++++++++++++++++++++++++++---------------- + 1 file changed, 50 insertions(+), 25 deletions(-) + +diff --git a/crypto/authenc.c b/crypto/authenc.c +index 3326c7343e867..ebaa035a54f4b 100644 +--- a/crypto/authenc.c ++++ b/crypto/authenc.c +@@ -39,7 +39,7 @@ struct authenc_request_ctx { + + static void authenc_request_complete(struct aead_request *req, int err) + { +- if (err != -EINPROGRESS) ++ if (err != -EINPROGRESS && err != -EBUSY) + aead_request_complete(req, err); + } + +@@ -109,27 +109,42 @@ static int crypto_authenc_setkey(struct crypto_aead *authenc, const u8 *key, + return err; + } + +-static void authenc_geniv_ahash_done(void *data, int err) ++static void authenc_geniv_ahash_finish(struct aead_request *req) + { +- struct aead_request *req = data; + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); + struct authenc_instance_ctx *ictx = aead_instance_ctx(inst); + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); + +- if (err) +- goto out; +- + scatterwalk_map_and_copy(ahreq->result, req->dst, + req->assoclen + req->cryptlen, + crypto_aead_authsize(authenc), 1); ++} + +-out: ++static void authenc_geniv_ahash_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); + aead_request_complete(req, err); + } + +-static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) ++/* ++ * Used when the ahash request was invoked in the async callback context ++ * of the previous skcipher request. Eat any EINPROGRESS notifications. ++ */ ++static void authenc_geniv_ahash_done2(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ if (!err) ++ authenc_geniv_ahash_finish(req); ++ authenc_request_complete(req, err); ++} ++ ++static int crypto_authenc_genicv(struct aead_request *req, unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -138,6 +153,7 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + struct crypto_ahash *auth = ctx->auth; + struct authenc_request_ctx *areq_ctx = aead_request_ctx(req); + struct ahash_request *ahreq = (void *)(areq_ctx->tail + ictx->reqoff); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *hash = areq_ctx->tail; + int err; + +@@ -148,7 +164,8 @@ static int crypto_authenc_genicv(struct aead_request *req, unsigned int flags) + ahash_request_set_crypt(ahreq, req->dst, hash, + req->assoclen + req->cryptlen); + ahash_request_set_callback(ahreq, flags, +- authenc_geniv_ahash_done, req); ++ mask ? authenc_geniv_ahash_done2 : ++ authenc_geniv_ahash_done, req); + + err = crypto_ahash_digest(ahreq); + if (err) +@@ -164,12 +181,11 @@ static void crypto_authenc_encrypt_done(void *data, int err) + { + struct aead_request *areq = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_genicv(areq, 0); +- +-out: ++ if (err) { ++ aead_request_complete(areq, err); ++ return; ++ } ++ err = crypto_authenc_genicv(areq, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(areq, err); + } + +@@ -222,11 +238,18 @@ static int crypto_authenc_encrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_genicv(req, aead_request_flags(req)); ++ return crypto_authenc_genicv(req, 0); ++} ++ ++static void authenc_decrypt_tail_done(void *data, int err) ++{ ++ struct aead_request *req = data; ++ ++ authenc_request_complete(req, err); + } + + static int crypto_authenc_decrypt_tail(struct aead_request *req, +- unsigned int flags) ++ unsigned int mask) + { + struct crypto_aead *authenc = crypto_aead_reqtfm(req); + struct aead_instance *inst = aead_alg_instance(authenc); +@@ -237,6 +260,7 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + struct skcipher_request *skreq = (void *)(areq_ctx->tail + + ictx->reqoff); + unsigned int authsize = crypto_aead_authsize(authenc); ++ unsigned int flags = aead_request_flags(req) & ~mask; + u8 *ihash = ahreq->result + authsize; + struct scatterlist *src, *dst; + +@@ -253,7 +277,9 @@ static int crypto_authenc_decrypt_tail(struct aead_request *req, + + skcipher_request_set_tfm(skreq, ctx->enc); + skcipher_request_set_callback(skreq, flags, +- req->base.complete, req->base.data); ++ mask ? authenc_decrypt_tail_done : ++ req->base.complete, ++ mask ? req : req->base.data); + skcipher_request_set_crypt(skreq, src, dst, + req->cryptlen - authsize, req->iv); + +@@ -264,12 +290,11 @@ static void authenc_verify_ahash_done(void *data, int err) + { + struct aead_request *req = data; + +- if (err) +- goto out; +- +- err = crypto_authenc_decrypt_tail(req, 0); +- +-out: ++ if (err) { ++ aead_request_complete(req, err); ++ return; ++ } ++ err = crypto_authenc_decrypt_tail(req, CRYPTO_TFM_REQ_MAY_SLEEP); + authenc_request_complete(req, err); + } + +@@ -299,7 +324,7 @@ static int crypto_authenc_decrypt(struct aead_request *req) + if (err) + return err; + +- return crypto_authenc_decrypt_tail(req, aead_request_flags(req)); ++ return crypto_authenc_decrypt_tail(req, 0); + } + + static int crypto_authenc_init_tfm(struct crypto_aead *tfm) +-- +2.51.0 + diff --git a/queue-6.6/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch b/queue-6.6/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch new file mode 100644 index 0000000000..17d9208375 --- /dev/null +++ b/queue-6.6/crypto-ccree-correctly-handle-return-of-sg_nents_for.patch @@ -0,0 +1,51 @@ +From 16ce7175f5230708b07fdaf8dbeda54eee4737b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 15:20:41 +0800 +Subject: crypto: ccree - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit 8700ce07c5c6bf27afa7b59a8d9cf58d783a7d5c ] + +Fix error handling in cc_map_hash_request_update where sg_nents_for_len +return value was assigned to u32, converting negative errors to large +positive values before passing to sg_copy_to_buffer. + +Check sg_nents_for_len return value and propagate errors before +assigning to areq_ctx->in_nents. + +Fixes: b7ec8530687a ("crypto: ccree - use std api when possible") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/ccree/cc_buffer_mgr.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c +index bcca55bff910e..286e0d4b8f95e 100644 +--- a/drivers/crypto/ccree/cc_buffer_mgr.c ++++ b/drivers/crypto/ccree/cc_buffer_mgr.c +@@ -1235,6 +1235,7 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + int rc = 0; + u32 dummy = 0; + u32 mapped_nents = 0; ++ int sg_nents; + + dev_dbg(dev, " update params : curr_buff=%pK curr_buff_cnt=0x%X nbytes=0x%X src=%pK curr_index=%u\n", + curr_buff, *curr_buff_cnt, nbytes, src, areq_ctx->buff_index); +@@ -1248,7 +1249,10 @@ int cc_map_hash_request_update(struct cc_drvdata *drvdata, void *ctx, + if (total_in_len < block_size) { + dev_dbg(dev, " less than one block: curr_buff=%pK *curr_buff_cnt=0x%X copy_to=%pK\n", + curr_buff, *curr_buff_cnt, &curr_buff[*curr_buff_cnt]); +- areq_ctx->in_nents = sg_nents_for_len(src, nbytes); ++ sg_nents = sg_nents_for_len(src, nbytes); ++ if (sg_nents < 0) ++ return sg_nents; ++ areq_ctx->in_nents = sg_nents; + sg_copy_to_buffer(src, areq_ctx->in_nents, + &curr_buff[*curr_buff_cnt], nbytes); + *curr_buff_cnt += nbytes; +-- +2.51.0 + diff --git a/queue-6.6/crypto-hisilicon-qm-restore-original-qos-values.patch b/queue-6.6/crypto-hisilicon-qm-restore-original-qos-values.patch new file mode 100644 index 0000000000..59b9e7899b --- /dev/null +++ b/queue-6.6/crypto-hisilicon-qm-restore-original-qos-values.patch @@ -0,0 +1,67 @@ +From 6e865a3c90f5efd63f6bfb419393804a7d07a390 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 19:27:39 +0800 +Subject: crypto: hisilicon/qm - restore original qos values + +From: nieweiqiang + +[ Upstream commit e7066160f5b4187ad9869b712fa7a35d3d5be6b9 ] + +When the new qos valus setting fails, restore to +the original qos values. + +Fixes: 72b010dc33b9 ("crypto: hisilicon/qm - supports writing QoS int the host") +Signed-off-by: nieweiqiang +Signed-off-by: Chenghai Huang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/hisilicon/qm.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c +index a2c6b28f4b84b..2c0ca68914e2f 100644 +--- a/drivers/crypto/hisilicon/qm.c ++++ b/drivers/crypto/hisilicon/qm.c +@@ -3555,6 +3555,7 @@ static int qm_clear_vft_config(struct hisi_qm *qm) + static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + { + struct device *dev = &qm->pdev->dev; ++ struct qm_shaper_factor t_factor; + u32 ir = qos * QM_QOS_RATE; + int ret, total_vfs, i; + +@@ -3562,6 +3563,7 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + if (fun_index > total_vfs) + return -EINVAL; + ++ memcpy(&t_factor, &qm->factor[fun_index], sizeof(t_factor)); + qm->factor[fun_index].func_qos = qos; + + ret = qm_get_shaper_para(ir, &qm->factor[fun_index]); +@@ -3575,11 +3577,21 @@ static int qm_func_shaper_enable(struct hisi_qm *qm, u32 fun_index, u32 qos) + ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); + if (ret) { + dev_err(dev, "type: %d, failed to set shaper vft!\n", i); +- return -EINVAL; ++ goto back_func_qos; + } + } + + return 0; ++ ++back_func_qos: ++ memcpy(&qm->factor[fun_index], &t_factor, sizeof(t_factor)); ++ for (i--; i >= ALG_TYPE_0; i--) { ++ ret = qm_set_vft_common(qm, SHAPER_VFT, fun_index, i, 1); ++ if (ret) ++ dev_err(dev, "failed to restore shaper vft during rollback!\n"); ++ } ++ ++ return -EINVAL; + } + + static u32 qm_get_shaper_vft_qos(struct hisi_qm *qm, u32 fun_index) +-- +2.51.0 + diff --git a/queue-6.6/crypto-starfive-correctly-handle-return-of-sg_nents_.patch b/queue-6.6/crypto-starfive-correctly-handle-return-of-sg_nents_.patch new file mode 100644 index 0000000000..e7603b5660 --- /dev/null +++ b/queue-6.6/crypto-starfive-correctly-handle-return-of-sg_nents_.patch @@ -0,0 +1,51 @@ +From fcc6bba4a7302406f940dff92e7ac0b98247f316 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:54:38 +0800 +Subject: crypto: starfive - Correctly handle return of sg_nents_for_len + +From: Haotian Zhang + +[ Upstream commit e9eb52037a529fbb307c290e9951a62dd728b03d ] + +The return value of sg_nents_for_len was assigned to an unsigned long +in starfive_hash_digest, causing negative error codes to be converted +to large positive integers. + +Add error checking for sg_nents_for_len and return immediately on +failure to prevent potential buffer overflows. + +Fixes: 7883d1b28a2b ("crypto: starfive - Add hash and HMAC support") +Signed-off-by: Haotian Zhang +Signed-off-by: Herbert Xu +Signed-off-by: Sasha Levin +--- + drivers/crypto/starfive/jh7110-hash.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/crypto/starfive/jh7110-hash.c b/drivers/crypto/starfive/jh7110-hash.c +index cc7650198d703..e973e73f866ba 100644 +--- a/drivers/crypto/starfive/jh7110-hash.c ++++ b/drivers/crypto/starfive/jh7110-hash.c +@@ -358,6 +358,7 @@ static int starfive_hash_digest(struct ahash_request *req) + struct starfive_cryp_ctx *ctx = crypto_ahash_ctx(tfm); + struct starfive_cryp_request_ctx *rctx = ahash_request_ctx(req); + struct starfive_cryp_dev *cryp = ctx->cryp; ++ int sg_len; + + memset(rctx, 0, sizeof(struct starfive_cryp_request_ctx)); + +@@ -366,7 +367,10 @@ static int starfive_hash_digest(struct ahash_request *req) + rctx->in_sg = req->src; + rctx->blksize = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + rctx->digsize = crypto_ahash_digestsize(tfm); +- rctx->in_sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ sg_len = sg_nents_for_len(rctx->in_sg, rctx->total); ++ if (sg_len < 0) ++ return sg_len; ++ rctx->in_sg_len = sg_len; + ctx->rctx = rctx; + + if (starfive_hash_check_aligned(rctx->in_sg, rctx->total, rctx->blksize)) +-- +2.51.0 + diff --git a/queue-6.6/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch b/queue-6.6/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch new file mode 100644 index 0000000000..e50669ae69 --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch @@ -0,0 +1,51 @@ +From 02cbb18e20821755e22fbb181c0c5d03885264e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 16:02:25 +0300 +Subject: drm/amd/display: Fix logical vs bitwise bug in + get_embedded_panel_info_v2_1() + +From: Dan Carpenter + +[ Upstream commit 1a79482699b4d1e43948d14f0c7193dc1dcad858 ] + +The .H_SYNC_POLARITY and .V_SYNC_POLARITY variables are 1 bit bitfields +of a u32. The ATOM_HSYNC_POLARITY define is 0x2 and the +ATOM_VSYNC_POLARITY is 0x4. When we do a bitwise negate of 0, 2, or 4 +then the last bit is always 1 so this code always sets .H_SYNC_POLARITY +and .V_SYNC_POLARITY to true. + +This code is instead intended to check if the ATOM_HSYNC_POLARITY or +ATOM_VSYNC_POLARITY flags are set and reverse the result. In other +words, it's supposed to be a logical negate instead of a bitwise negate. + +Fixes: ae79c310b1a6 ("drm/amd/display: Add DCE12 bios parser support") +Signed-off-by: Dan Carpenter +Reviewed-by: Alex Hung +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +index 384ddb28e6f6d..c0a705888cb5b 100644 +--- a/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c ++++ b/drivers/gpu/drm/amd/display/dc/bios/bios_parser2.c +@@ -1477,10 +1477,10 @@ static enum bp_result get_embedded_panel_info_v2_1( + /* not provided by VBIOS */ + info->lcd_timing.misc_info.HORIZONTAL_CUT_OFF = 0; + +- info->lcd_timing.misc_info.H_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_HSYNC_POLARITY); +- info->lcd_timing.misc_info.V_SYNC_POLARITY = ~(uint32_t) (lvds->lcd_timing.miscinfo +- & ATOM_VSYNC_POLARITY); ++ info->lcd_timing.misc_info.H_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_HSYNC_POLARITY); ++ info->lcd_timing.misc_info.V_SYNC_POLARITY = !(lvds->lcd_timing.miscinfo & ++ ATOM_VSYNC_POLARITY); + + /* not provided by VBIOS */ + info->lcd_timing.misc_info.VERTICAL_CUT_OFF = 0; +-- +2.51.0 + diff --git a/queue-6.6/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch b/queue-6.6/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch new file mode 100644 index 0000000000..52f96b7e16 --- /dev/null +++ b/queue-6.6/drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch @@ -0,0 +1,71 @@ +From 34d9b13e49db25e8a3080c4c884a8c35b8c7d305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 21 Sep 2025 13:53:05 +0800 +Subject: drm/mediatek: Fix CCORR mtk_ctm_s31_32_to_s1_n function issue + +From: Jay Liu + +[ Upstream commit 20ac36b71c53b8c36c6903b5ca87c75226700a97 ] + +if matrixbit is 11, +The range of color matrix is from 0 to (BIT(12) - 1). +Values from 0 to (BIT(11) - 1) represent positive numbers, +values from BIT(11) to (BIT(12) - 1) represent negative numbers. +For example, -1 need converted to 8191. +so convert S31.32 to HW Q2.11 format by drm_color_ctm_s31_32_to_qm_n, +and set int_bits to 2. + +Fixes: 738ed4156fba ("drm/mediatek: Add matrix_bits private data for ccorr") +Reviewed-by: AngeloGioacchino Del Regno +Signed-off-by: Jay Liu +Link: https://patchwork.kernel.org/project/dri-devel/patch/20250921055416.25588-2-jay.liu@mediatek.com/ +Signed-off-by: Chun-Kuang Hu +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/mediatek/mtk_disp_ccorr.c | 23 +---------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +index 4234ff7485e88..2126cb95ae920 100644 +--- a/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c ++++ b/drivers/gpu/drm/mediatek/mtk_disp_ccorr.c +@@ -80,27 +80,6 @@ void mtk_ccorr_stop(struct device *dev) + writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN); + } + +-/* Converts a DRM S31.32 value to the HW S1.n format. */ +-static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n) +-{ +- u16 r; +- +- /* Sign bit. */ +- r = in & BIT_ULL(63) ? BIT(n + 1) : 0; +- +- if ((in & GENMASK_ULL(62, 33)) > 0) { +- /* identity value 0x100000000 -> 0x400(mt8183), */ +- /* identity value 0x100000000 -> 0x800(mt8192), */ +- /* if bigger this, set it to max 0x7ff. */ +- r |= GENMASK(n, 0); +- } else { +- /* take the n+1 most important bits. */ +- r |= (in >> (32 - n)) & GENMASK(n, 0); +- } +- +- return r; +-} +- + void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + { + struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev); +@@ -119,7 +98,7 @@ void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state) + input = ctm->matrix; + + for (i = 0; i < ARRAY_SIZE(coeffs); i++) +- coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits); ++ coeffs[i] = drm_color_ctm_s31_32_to_qm_n(input[i], 2, matrix_bits); + + mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1], + &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0); +-- +2.51.0 + diff --git a/queue-6.6/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch b/queue-6.6/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch new file mode 100644 index 0000000000..25e2aeae41 --- /dev/null +++ b/queue-6.6/drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch @@ -0,0 +1,42 @@ +From 790ddb384814ef28b891505c3a03ed8cf46b914e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:40:50 +0200 +Subject: drm/msm/a2xx: stop over-complaining about the legacy firmware + +From: Dmitry Baryshkov + +[ Upstream commit a3a22373fce576560757f5616eb48dbf85891d9c ] + +If the rootfs have a legacy A200 firmware, currently the driver will +complain each time the hw is reinited (which can happen a lot). E.g. +with GL testsuite the hw is reinited after each test, spamming the +console. + +Make sure that the message is printed only once: when we detect the +firmware that doesn't support protection. + +Fixes: 302295070d3c ("drm/msm/a2xx: support loading legacy (iMX) firmware") +Signed-off-by: Dmitry Baryshkov +Patchwork: https://patchwork.freedesktop.org/patch/688098/ +Signed-off-by: Rob Clark +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/msm/adreno/a2xx_gpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +index 0d8133f3174be..535c89ce5d62e 100644 +--- a/drivers/gpu/drm/msm/adreno/a2xx_gpu.c ++++ b/drivers/gpu/drm/msm/adreno/a2xx_gpu.c +@@ -234,7 +234,7 @@ static int a2xx_hw_init(struct msm_gpu *gpu) + * word (0x20xxxx for A200, 0x220xxx for A220, 0x225xxx for A225). + * Older firmware files, which lack protection support, have 0 instead. + */ +- if (ptr[1] == 0) { ++ if (ptr[1] == 0 && !a2xx_gpu->protection_disabled) { + dev_warn(gpu->dev->dev, + "Legacy firmware detected, disabling protection support\n"); + a2xx_gpu->protection_disabled = true; +-- +2.51.0 + diff --git a/queue-6.6/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch b/queue-6.6/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch new file mode 100644 index 0000000000..0b459aced6 --- /dev/null +++ b/queue-6.6/drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch @@ -0,0 +1,55 @@ +From 6d9b6a2f8b496c9950e074fb65bab5aed788ea8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 17:03:22 -0600 +Subject: drm/nouveau: restrict the flush page to a 32-bit address + +From: Timur Tabi + +[ Upstream commit 04d98b3452331fa53ec3b698b66273af6ef73288 ] + +The flush page DMA address is stored in a special register that is not +associated with the GPU's standard DMA range. For example, on Turing, +the GPU's MMU can handle 47-bit addresses, but the flush page address +register is limited to 40 bits. + +At the point during device initialization when the flush page is +allocated, the DMA mask is still at its default of 32 bits. So even +though it's unlikely that the flush page could exist above a 40-bit +address, the dma_map_page() call could fail, e.g. if IOMMU is disabled +and the address is above 32 bits. The simplest way to achieve all +constraints is to allocate the page in the DMA32 zone. Since the flush +page is literally just a page, this is an acceptable limitation. The +alternative is to temporarily set the DMA mask to 40 (or 52 for Hopper +and later) bits, but that could have unforseen side effects. + +In situations where the flush page is allocated above 32 bits and IOMMU +is disabled, you will get an error like this: + +nouveau 0000:65:00.0: DMA addr 0x0000000107c56000+4096 overflow (mask ffffffff, bus limit 0). + +Fixes: 5728d064190e ("drm/nouveau/fb: handle sysmem flush page from common code") +Signed-off-by: Timur Tabi +Reviewed-by: Lyude Paul +Signed-off-by: Lyude Paul +Link: https://patch.msgid.link/20251113230323.1271726-1-ttabi@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +index 8a286a9349ac6..7ce1b65e2c1c2 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/base.c +@@ -279,7 +279,7 @@ nvkm_fb_ctor(const struct nvkm_fb_func *func, struct nvkm_device *device, + mutex_init(&fb->tags.mutex); + + if (func->sysmem.flush_page_init) { +- fb->sysmem.flush_page = alloc_page(GFP_KERNEL | __GFP_ZERO); ++ fb->sysmem.flush_page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); + if (!fb->sysmem.flush_page) + return -ENOMEM; + +-- +2.51.0 + diff --git a/queue-6.6/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch b/queue-6.6/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch new file mode 100644 index 0000000000..dd973b14f5 --- /dev/null +++ b/queue-6.6/drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch @@ -0,0 +1,42 @@ +From 86ddf55e194877d5ab0d56de1b12e21cd973b29f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Sep 2025 18:39:57 +0200 +Subject: drm/panel: visionox-rm69299: Don't clear all mode flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guido Günther + +[ Upstream commit 39144b611e9cd4f5814f4098c891b545dd70c536 ] + +Don't clear all mode flags. We only want to maek sure we use HS mode +during unprepare. + +Fixes: c7f66d32dd431 ("drm/panel: add support for rm69299 visionox panel") +Reviewed-by: Neil Armstrong +Signed-off-by: Guido Günther +Reviewed-by: Dmitry Baryshkov +Signed-off-by: Neil Armstrong +Link: https://lore.kernel.org/r/20250910-shift6mq-panel-v3-2-a7729911afb9@sigxcpu.org +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/panel/panel-visionox-rm69299.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/panel/panel-visionox-rm69299.c b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +index 6e946e5a036ee..fa784b9998eb0 100644 +--- a/drivers/gpu/drm/panel/panel-visionox-rm69299.c ++++ b/drivers/gpu/drm/panel/panel-visionox-rm69299.c +@@ -64,7 +64,7 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) + struct visionox_rm69299 *ctx = panel_to_ctx(panel); + int ret; + +- ctx->dsi->mode_flags = 0; ++ ctx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM; + + ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); + if (ret < 0) +-- +2.51.0 + diff --git a/queue-6.6/drm-vgem-fence-fix-potential-deadlock-on-release.patch b/queue-6.6/drm-vgem-fence-fix-potential-deadlock-on-release.patch new file mode 100644 index 0000000000..92ea59354c --- /dev/null +++ b/queue-6.6/drm-vgem-fence-fix-potential-deadlock-on-release.patch @@ -0,0 +1,268 @@ +From 2d98c71d821ea3b6f1f66578e99c0286fc9e4958 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 26 Sep 2025 17:26:27 +0200 +Subject: drm/vgem-fence: Fix potential deadlock on release +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Janusz Krzysztofik + +[ Upstream commit 78b4d6463e9e69e5103f98b367f8984ad12cdc6f ] + +A timer that expires a vgem fence automatically in 10 seconds is now +released with timer_delete_sync() from fence->ops.release() called on last +dma_fence_put(). In some scenarios, it can run in IRQ context, which is +not safe unless TIMER_IRQSAFE is used. One potentially risky scenario was +demonstrated in Intel DRM CI trybot, BAT run on machine bat-adlp-6, while +working on new IGT subtests syncobj_timeline@stress-* as user space +replacements of some problematic test cases of a dma-fence-chain selftest +[1]. + +[117.004338] ================================ +[117.004340] WARNING: inconsistent lock state +[117.004342] 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 Tainted: G S U +[117.004346] -------------------------------- +[117.004347] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. +[117.004349] swapper/0/0 [HC1[1]:SC1[1]:HE0:SE0] takes: +[117.004352] ffff888138f86aa8 ((&fence->timer)){?.-.}-{0:0}, at: __timer_delete_sync+0x4b/0x190 +[117.004361] {HARDIRQ-ON-W} state was registered at: +[117.004363] lock_acquire+0xc4/0x2e0 +[117.004366] call_timer_fn+0x80/0x2a0 +[117.004368] __run_timers+0x231/0x310 +[117.004370] run_timer_softirq+0x76/0xe0 +[117.004372] handle_softirqs+0xd4/0x4d0 +[117.004375] __irq_exit_rcu+0x13f/0x160 +[117.004377] irq_exit_rcu+0xe/0x20 +[117.004379] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004382] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004385] cpuidle_enter_state+0x12b/0x8a0 +[117.004388] cpuidle_enter+0x2e/0x50 +[117.004393] call_cpuidle+0x22/0x60 +[117.004395] do_idle+0x1fd/0x260 +[117.004398] cpu_startup_entry+0x29/0x30 +[117.004401] start_secondary+0x12d/0x160 +[117.004404] common_startup_64+0x13e/0x141 +[117.004407] irq event stamp: 2282669 +[117.004409] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.004414] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.004419] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.004423] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.004426] +other info that might help us debug this: +[117.004429] Possible unsafe locking scenario: +[117.004432] CPU0 +[117.004433] ---- +[117.004434] lock((&fence->timer)); +[117.004436] +[117.004438] lock((&fence->timer)); +[117.004440] + *** DEADLOCK *** +[117.004443] 1 lock held by swapper/0/0: +[117.004445] #0: ffffc90000003d50 ((&fence->timer)){?.-.}-{0:0}, at: call_timer_fn+0x7a/0x2a0 +[117.004450] +stack backtrace: +[117.004453] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004455] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004455] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004456] Call Trace: +[117.004456] +[117.004457] dump_stack_lvl+0x91/0xf0 +[117.004460] dump_stack+0x10/0x20 +[117.004461] print_usage_bug.part.0+0x260/0x360 +[117.004463] mark_lock+0x76e/0x9c0 +[117.004465] ? register_lock_class+0x48/0x4a0 +[117.004467] __lock_acquire+0xbc3/0x2860 +[117.004469] lock_acquire+0xc4/0x2e0 +[117.004470] ? __timer_delete_sync+0x4b/0x190 +[117.004472] ? __timer_delete_sync+0x4b/0x190 +[117.004473] __timer_delete_sync+0x68/0x190 +[117.004474] ? __timer_delete_sync+0x4b/0x190 +[117.004475] timer_delete_sync+0x10/0x20 +[117.004476] vgem_fence_release+0x19/0x30 [vgem] +[117.004478] dma_fence_release+0xc1/0x3b0 +[117.004480] ? dma_fence_release+0xa1/0x3b0 +[117.004481] dma_fence_chain_release+0xe7/0x130 +[117.004483] dma_fence_release+0xc1/0x3b0 +[117.004484] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004485] dma_fence_chain_irq_work+0x59/0x80 +[117.004487] irq_work_single+0x75/0xa0 +[117.004490] irq_work_run_list+0x33/0x60 +[117.004491] irq_work_run+0x18/0x40 +[117.004493] __sysvec_irq_work+0x35/0x170 +[117.004494] sysvec_irq_work+0x47/0xc0 +[117.004496] asm_sysvec_irq_work+0x1b/0x20 +[117.004497] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004499] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004499] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004500] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004501] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004502] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004502] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004502] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004506] dma_fence_signal+0x49/0xb0 +[117.004507] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004508] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004509] call_timer_fn+0xa1/0x2a0 +[117.004512] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004513] __run_timers+0x231/0x310 +[117.004514] ? tmigr_handle_remote+0x2ac/0x560 +[117.004517] timer_expire_remote+0x46/0x70 +[117.004518] tmigr_handle_remote+0x433/0x560 +[117.004520] ? __run_timers+0x239/0x310 +[117.004521] ? run_timer_softirq+0x21/0xe0 +[117.004522] ? lock_release+0xce/0x2a0 +[117.004524] run_timer_softirq+0xcf/0xe0 +[117.004525] handle_softirqs+0xd4/0x4d0 +[117.004526] __irq_exit_rcu+0x13f/0x160 +[117.004527] irq_exit_rcu+0xe/0x20 +[117.004528] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004529] +[117.004529] +[117.004529] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004530] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004532] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004532] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004533] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004533] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004534] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004534] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004534] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004537] ? cpuidle_enter_state+0x125/0x8a0 +[117.004538] ? sched_clock_noinstr+0x9/0x10 +[117.004540] cpuidle_enter+0x2e/0x50 +[117.004542] call_cpuidle+0x22/0x60 +[117.004542] do_idle+0x1fd/0x260 +[117.004544] cpu_startup_entry+0x29/0x30 +[117.004546] rest_init+0x104/0x200 +[117.004548] start_kernel+0x93d/0xbd0 +[117.004550] ? load_ucode_intel_bsp+0x2a/0x90 +[117.004551] ? sme_unmap_bootdata+0x14/0x80 +[117.004554] x86_64_start_reservations+0x18/0x30 +[117.004555] x86_64_start_kernel+0xfd/0x150 +[117.004556] ? soft_restart_cpu+0x14/0x14 +[117.004558] common_startup_64+0x13e/0x141 +[117.004560] +[117.004565] ------------[ cut here ]------------ +[117.004692] WARNING: CPU: 0 PID: 0 at kernel/time/timer.c:1610 __timer_delete_sync+0x126/0x190 +[117.004697] Modules linked in: vgem snd_hda_codec_intelhdmi snd_hda_codec_hdmi i915 prime_numbers ttm drm_buddy drm_display_helper cec rc_core i2c_algo_bit hid_sensor_custom hid_sensor_hub hid_generic intel_ishtp_hid hid intel_uncore_frequency intel_uncore_frequency_common x86_pkg_temp_thermal intel_powerclamp cmdlinepart ee1004 r8153_ecm spi_nor coretemp cdc_ether mei_pxp mei_hdcp usbnet mtd intel_rapl_msr wmi_bmof kvm_intel snd_hda_intel snd_intel_dspcfg processor_thermal_device_pci kvm snd_hda_codec processor_thermal_device irqbypass processor_thermal_wt_hint polyval_clmulni platform_temperature_control snd_hda_core ghash_clmulni_intel processor_thermal_rfim spi_pxa2xx_platform snd_hwdep aesni_intel processor_thermal_rapl dw_dmac snd_pcm dw_dmac_core intel_rapl_common r8152 rapl mii intel_cstate spi_pxa2xx_core i2c_i801 processor_thermal_wt_req snd_timer i2c_mux mei_me intel_ish_ipc processor_thermal_power_floor e1000e snd i2c_smbus spi_intel_pci processor_thermal_mbox mei soundcore intel_ishtp thunderbolt idma64 +[117.004733] spi_intel int340x_thermal_zone igen6_edac binfmt_misc intel_skl_int3472_tps68470 intel_pmc_core tps68470_regulator video clk_tps68470 pmt_telemetry pmt_discovery nls_iso8859_1 pmt_class intel_pmc_ssram_telemetry intel_skl_int3472_discrete int3400_thermal intel_hid intel_skl_int3472_common acpi_thermal_rel intel_vsec wmi pinctrl_tigerlake acpi_tad sparse_keymap acpi_pad dm_multipath msr nvme_fabrics fuse efi_pstore nfnetlink autofs4 +[117.004782] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Tainted: G S U 6.17.0-rc7-CI_DRM_17270-g7644974e648c+ #1 PREEMPT(voluntary) +[117.004787] Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +[117.004789] Hardware name: Intel Corporation Alder Lake Client Platform/AlderLake-P DDR4 RVP, BIOS RPLPFWI1.R00.4035.A00.2301200723 01/20/2023 +[117.004793] RIP: 0010:__timer_delete_sync+0x126/0x190 +[117.004795] Code: 31 c0 45 31 c9 c3 cc cc cc cc 48 8b 75 d0 45 84 f6 74 63 49 c7 45 18 00 00 00 00 48 89 c7 e8 51 46 39 01 f3 90 e9 66 ff ff ff <0f> 0b e9 5f ff ff ff e8 ee e4 0c 00 49 8d 5d 28 45 31 c9 31 c9 4c +[117.004801] RSP: 0018:ffffc90000003a40 EFLAGS: 00010046 +[117.004804] RAX: ffffffff815093fb RBX: ffff888138f86aa8 RCX: 0000000000000000 +[117.004807] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004809] RBP: ffffc90000003a70 R08: 0000000000000000 R09: 0000000000000000 +[117.004812] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff815093fb +[117.004814] R13: ffff888138f86a80 R14: 0000000000000000 R15: 0000000000000000 +[117.004817] FS: 0000000000000000(0000) GS:ffff88890b0f7000(0000) knlGS:0000000000000000 +[117.004820] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[117.004823] CR2: 00005db8131eb7f0 CR3: 0000000003448000 CR4: 0000000000f52ef0 +[117.004826] PKRU: 55555554 +[117.004827] Call Trace: +[117.004829] +[117.004831] timer_delete_sync+0x10/0x20 +[117.004833] vgem_fence_release+0x19/0x30 [vgem] +[117.004836] dma_fence_release+0xc1/0x3b0 +[117.004838] ? dma_fence_release+0xa1/0x3b0 +[117.004841] dma_fence_chain_release+0xe7/0x130 +[117.004844] dma_fence_release+0xc1/0x3b0 +[117.004847] ? _raw_spin_unlock_irqrestore+0x27/0x80 +[117.004850] dma_fence_chain_irq_work+0x59/0x80 +[117.004853] irq_work_single+0x75/0xa0 +[117.004857] irq_work_run_list+0x33/0x60 +[117.004860] irq_work_run+0x18/0x40 +[117.004863] __sysvec_irq_work+0x35/0x170 +[117.004865] sysvec_irq_work+0x47/0xc0 +[117.004868] asm_sysvec_irq_work+0x1b/0x20 +[117.004871] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80 +[117.004874] Code: 00 75 1c 65 ff 0d d9 34 68 01 74 20 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 cc cc cc cc e8 7f 9d d3 fe fb 0f 1f 44 00 00 d7 0f 1f 44 00 00 5b 41 5c 5d 31 c0 31 d2 31 c9 31 f6 31 ff c3 +[117.004879] RSP: 0018:ffffc90000003cf0 EFLAGS: 00000246 +[117.004882] RAX: 0000000000000000 RBX: ffff888155e94c40 RCX: 0000000000000000 +[117.004884] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004887] RBP: ffffc90000003d00 R08: 0000000000000000 R09: 0000000000000000 +[117.004890] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000246 +[117.004892] R13: 0000000000000001 R14: 0000000000000246 R15: ffff888155e94c80 +[117.004897] dma_fence_signal+0x49/0xb0 +[117.004899] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004902] vgem_fence_timeout+0x12/0x20 [vgem] +[117.004904] call_timer_fn+0xa1/0x2a0 +[117.004908] ? __pfx_vgem_fence_timeout+0x10/0x10 [vgem] +[117.004910] __run_timers+0x231/0x310 +[117.004913] ? tmigr_handle_remote+0x2ac/0x560 +[117.004917] timer_expire_remote+0x46/0x70 +[117.004919] tmigr_handle_remote+0x433/0x560 +[117.004923] ? __run_timers+0x239/0x310 +[117.004925] ? run_timer_softirq+0x21/0xe0 +[117.004928] ? lock_release+0xce/0x2a0 +[117.004931] run_timer_softirq+0xcf/0xe0 +[117.004933] handle_softirqs+0xd4/0x4d0 +[117.004936] __irq_exit_rcu+0x13f/0x160 +[117.004938] irq_exit_rcu+0xe/0x20 +[117.004940] sysvec_apic_timer_interrupt+0xa0/0xc0 +[117.004943] +[117.004944] +[117.004946] asm_sysvec_apic_timer_interrupt+0x1b/0x20 +[117.004949] RIP: 0010:cpuidle_enter_state+0x12b/0x8a0 +[117.004953] Code: 48 0f a3 05 97 ce 0e 01 0f 82 2e 03 00 00 31 ff e8 8a 41 bd fe 80 7d d0 00 0f 85 11 03 00 00 e8 8b 06 d5 fe fb 0f 1f 44 00 00 <45> 85 f6 0f 88 67 02 00 00 4d 63 ee 49 83 fd 0a 0f 83 34 06 00 00 +[117.004961] RSP: 0018:ffffffff83403d88 EFLAGS: 00000246 +[117.004963] RAX: 0000000000000000 RBX: ffff88888f046440 RCX: 0000000000000000 +[117.004966] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[117.004968] RBP: ffffffff83403dd8 R08: 0000000000000000 R09: 0000000000000000 +[117.004971] R10: 0000000000000000 R11: 0000000000000000 R12: ffffffff837cbe80 +[117.004974] R13: 0000000000000004 R14: 0000000000000004 R15: 0000001ad1df466b +[117.004978] ? cpuidle_enter_state+0x125/0x8a0 +[117.004981] ? sched_clock_noinstr+0x9/0x10 +[117.004985] cpuidle_enter+0x2e/0x50 +[117.004989] call_cpuidle+0x22/0x60 +[117.004991] do_idle+0x1fd/0x260 +[117.005001] cpu_startup_entry+0x29/0x30 +[117.005004] rest_init+0x104/0x200 +[117.005008] start_kernel+0x93d/0xbd0 +[117.005011] ? load_ucode_intel_bsp+0x2a/0x90 +[117.005014] ? sme_unmap_bootdata+0x14/0x80 +[117.005017] x86_64_start_reservations+0x18/0x30 +[117.005020] x86_64_start_kernel+0xfd/0x150 +[117.005023] ? soft_restart_cpu+0x14/0x14 +[117.005026] common_startup_64+0x13e/0x141 +[117.005030] +[117.005032] irq event stamp: 2282669 +[117.005034] hardirqs last enabled at (2282668): [] _raw_spin_unlock_irqrestore+0x51/0x80 +[117.005038] hardirqs last disabled at (2282669): [] sysvec_irq_work+0x11/0xc0 +[117.005043] softirqs last enabled at (2254702): [] __do_softirq+0x10/0x18 +[117.005047] softirqs last disabled at (2254725): [] __irq_exit_rcu+0x13f/0x160 +[117.005051] ---[ end trace 0000000000000000 ]--- + +Make the timer IRQ safe. + +[1] https://patchwork.freedesktop.org/series/154987/#rev2 + +Fixes: 4077798484459 ("drm/vgem: Attach sw fences to exported vGEM dma-buf (ioctl)") +Signed-off-by: Janusz Krzysztofik +Reviewed-by: Christian König +Link: https://lore.kernel.org/r/20250926152628.2165080-2-janusz.krzysztofik@linux.intel.com +Signed-off-by: Maarten Lankhorst +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/vgem/vgem_fence.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/vgem/vgem_fence.c b/drivers/gpu/drm/vgem/vgem_fence.c +index e157541783959..d066345d5930b 100644 +--- a/drivers/gpu/drm/vgem/vgem_fence.c ++++ b/drivers/gpu/drm/vgem/vgem_fence.c +@@ -94,7 +94,7 @@ static struct dma_fence *vgem_fence_create(struct vgem_file *vfile, + dma_fence_init(&fence->base, &vgem_fence_ops, &fence->lock, + dma_fence_context_alloc(1), 1); + +- timer_setup(&fence->timer, vgem_fence_timeout, 0); ++ timer_setup(&fence->timer, vgem_fence_timeout, TIMER_IRQSAFE); + + /* We force the fence to expire within 10s to prevent driver hangs */ + mod_timer(&fence->timer, jiffies + VGEM_FENCE_TIMEOUT); +-- +2.51.0 + diff --git a/queue-6.6/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch b/queue-6.6/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch new file mode 100644 index 0000000000..0824dc9acd --- /dev/null +++ b/queue-6.6/dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch @@ -0,0 +1,57 @@ +From cf3868386b769e0dc1cc6e5a5793df9e8d0ba5ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 1 Nov 2025 09:59:40 +0530 +Subject: dt-bindings: PCI: amlogic: Fix the register name of the DBI region + +From: Manivannan Sadhasivam + +[ Upstream commit 4813dea9e272ba0a57c50b8d51d440dd8e3ccdd7 ] + +Binding incorrectly specifies the 'DBI' region as 'ELBI'. DBI is a must +have region for DWC controllers as it has the Root Port and controller +specific registers, while ELBI has optional registers. + +Hence, fix the binding. Though this is an ABI break, this change is needed +to accurately describe the PCI memory map. + +Fixes: 7cd210391101 ("dt-bindings: PCI: meson: add DT bindings for Amlogic Meson PCIe controller") +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20251101-pci-meson-fix-v1-1-c50dcc56ed6a@oss.qualcomm.com +Signed-off-by: Sasha Levin +--- + Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +index a5bd90bc0712e..9c3b8e65c42a3 100644 +--- a/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml ++++ b/Documentation/devicetree/bindings/pci/amlogic,axg-pcie.yaml +@@ -36,13 +36,13 @@ properties: + + reg: + items: +- - description: External local bus interface registers ++ - description: Data Bus Interface registers + - description: Meson designed configuration registers + - description: PCIe configuration space + + reg-names: + items: +- - const: elbi ++ - const: dbi + - const: cfg + - const: config + +@@ -113,7 +113,7 @@ examples: + pcie: pcie@f9800000 { + compatible = "amlogic,axg-pcie", "snps,dw-pcie"; + reg = <0xf9800000 0x400000>, <0xff646000 0x2000>, <0xf9f00000 0x100000>; +- reg-names = "elbi", "cfg", "config"; ++ reg-names = "dbi", "cfg", "config"; + interrupts = ; + clocks = <&pclk>, <&clk_port>, <&clk_phy>; + clock-names = "pclk", "port", "general"; +-- +2.51.0 + diff --git a/queue-6.6/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch b/queue-6.6/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch new file mode 100644 index 0000000000..1b78f919e0 --- /dev/null +++ b/queue-6.6/efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch @@ -0,0 +1,71 @@ +From 2a2bbb1f1688aeaaf9fb54178c1daffe1b38eb48 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:23 +0000 +Subject: efi/libstub: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit 84361123413efc84b06f3441c6c827b95d902732 ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags Bits above the + physical address width of the system (i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The pgd value is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: cb1c9e02b0c1 ("x86/efistub: Perform 4/5 level paging switch from the stub") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Link: https://patch.msgid.link/20251103141002.2280812-3-usamaarif642@gmail.com +Signed-off-by: Sasha Levin +--- + drivers/firmware/efi/libstub/x86-5lvl.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/firmware/efi/libstub/x86-5lvl.c b/drivers/firmware/efi/libstub/x86-5lvl.c +index 479dd445acdcf..267b1c5312540 100644 +--- a/drivers/firmware/efi/libstub/x86-5lvl.c ++++ b/drivers/firmware/efi/libstub/x86-5lvl.c +@@ -66,7 +66,7 @@ void efi_5level_switch(void) + bool have_la57 = native_read_cr4() & X86_CR4_LA57; + bool need_toggle = want_la57 ^ have_la57; + u64 *pgt = (void *)la57_toggle + PAGE_SIZE; +- u64 *cr3 = (u64 *)__native_read_cr3(); ++ pgd_t *cr3 = (pgd_t *)native_read_cr3_pa(); + u64 *new_cr3; + + if (!la57_toggle || !need_toggle) +@@ -82,7 +82,7 @@ void efi_5level_switch(void) + new_cr3[0] = (u64)cr3 | _PAGE_TABLE_NOENC; + } else { + /* take the new root table pointer from the current entry #0 */ +- new_cr3 = (u64 *)(cr3[0] & PAGE_MASK); ++ new_cr3 = (u64 *)(native_pgd_val(cr3[0]) & PTE_PFN_MASK); + + /* copy the new root table if it is not 32-bit addressable */ + if ((u64)new_cr3 > U32_MAX) +-- +2.51.0 + diff --git a/queue-6.6/ext4-correct-the-checking-of-quota-files-before-movi.patch b/queue-6.6/ext4-correct-the-checking-of-quota-files-before-movi.patch new file mode 100644 index 0000000000..b4b999aa10 --- /dev/null +++ b/queue-6.6/ext4-correct-the-checking-of-quota-files-before-movi.patch @@ -0,0 +1,38 @@ +From e4d2956de212e129d2491b8250fc0218611e24ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 09:51:17 +0800 +Subject: ext4: correct the checking of quota files before moving extents + +From: Zhang Yi + +[ Upstream commit a2e5a3cea4b18f6e2575acc444a5e8cce1fc8260 ] + +The move extent operation should return -EOPNOTSUPP if any of the inodes +is a quota inode, rather than requiring both to be quota inodes. + +Fixes: 02749a4c2082 ("ext4: add ext4_is_quota_file()") +Signed-off-by: Zhang Yi +Reviewed-by: Jan Kara +Message-ID: <20251013015128.499308-2-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/move_extent.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c +index c566161127cd7..a3b0acca02ca5 100644 +--- a/fs/ext4/move_extent.c ++++ b/fs/ext4/move_extent.c +@@ -486,7 +486,7 @@ mext_check_arguments(struct inode *orig_inode, + return -ETXTBSY; + } + +- if (ext4_is_quota_file(orig_inode) && ext4_is_quota_file(donor_inode)) { ++ if (ext4_is_quota_file(orig_inode) || ext4_is_quota_file(donor_inode)) { + ext4_debug("ext4 move extent: The argument files should not be quota files [ino:orig %lu, donor %lu]\n", + orig_inode->i_ino, donor_inode->i_ino); + return -EOPNOTSUPP; +-- +2.51.0 + diff --git a/queue-6.6/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch b/queue-6.6/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch new file mode 100644 index 0000000000..7b39f69fc1 --- /dev/null +++ b/queue-6.6/ext4-improve-integrity-checking-in-__mb_check_buddy-.patch @@ -0,0 +1,148 @@ +From dfbe35b621efa83539482600a126756627afb916 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 14:06:14 +0800 +Subject: ext4: improve integrity checking in __mb_check_buddy by enhancing + order-0 validation + +From: Yongjian Sun + +[ Upstream commit d9ee3ff810f1cc0e253c9f2b17b668b973cb0e06 ] + +When the MB_CHECK_ASSERT macro is enabled, we found that the +current validation logic in __mb_check_buddy has a gap in +detecting certain invalid buddy states, particularly related +to order-0 (bitmap) bits. + +The original logic consists of three steps: +1. Validates higher-order buddies: if a higher-order bit is +set, at most one of the two corresponding lower-order bits +may be free; if a higher-order bit is clear, both lower-order +bits must be allocated (and their bitmap bits must be 0). +2. For any set bit in order-0, ensures all corresponding +higher-order bits are not free. +3. Verifies that all preallocated blocks (pa) in the group +have pa_pstart within bounds and their bitmap bits marked as +allocated. + +However, this approach fails to properly validate cases where +order-0 bits are incorrectly cleared (0), allowing some invalid +configurations to pass: + + corrupt integral + +order 3 1 1 +order 2 1 1 1 1 +order 1 1 1 1 1 1 1 1 1 +order 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + +Here we get two adjacent free blocks at order-0 with inconsistent +higher-order state, and the right one shows the correct scenario. + +The root cause is insufficient validation of order-0 zero bits. +To fix this and improve completeness without significant performance +cost, we refine the logic: + +1. Maintain the top-down higher-order validation, but we no longer +check the cases where the higher-order bit is 0, as this case will +be covered in step 2. +2. Enhance order-0 checking by examining pairs of bits: + - If either bit in a pair is set (1), all corresponding + higher-order bits must not be free. + - If both bits are clear (0), then exactly one of the + corresponding higher-order bits must be free +3. Keep the preallocation (pa) validation unchanged. + +This change closes the validation gap, ensuring illegal buddy states +involving order-0 are correctly detected, while removing redundant +checks and maintaining efficiency. + +Fixes: c9de560ded61f ("ext4: Add multi block allocator for ext4") +Suggested-by: Jan Kara +Signed-off-by: Yongjian Sun +Reviewed-by: Baokun Li +Reviewed-by: Jan Kara +Message-ID: <20251106060614.631382-3-sunyongjian@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 49 +++++++++++++++++++++++++++++++---------------- + 1 file changed, 32 insertions(+), 17 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index 9721ae0ff92ed..5304497c60e1f 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -676,6 +676,24 @@ do { \ + } \ + } while (0) + ++/* ++ * Perform buddy integrity check with the following steps: ++ * ++ * 1. Top-down validation (from highest order down to order 1, excluding order-0 bitmap): ++ * For each pair of adjacent orders, if a higher-order bit is set (indicating a free block), ++ * at most one of the two corresponding lower-order bits may be clear (free). ++ * ++ * 2. Order-0 (bitmap) validation, performed on bit pairs: ++ * - If either bit in a pair is set (1, allocated), then all corresponding higher-order bits ++ * must not be free (0). ++ * - If both bits in a pair are clear (0, free), then exactly one of the corresponding ++ * higher-order bits must be free (0). ++ * ++ * 3. Preallocation (pa) list validation: ++ * For each preallocated block (pa) in the group: ++ * - Verify that pa_pstart falls within the bounds of this block group. ++ * - Ensure the corresponding bit(s) in the order-0 bitmap are marked as allocated (1). ++ */ + static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { +@@ -717,15 +735,6 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + continue; + } + +- /* both bits in buddy2 must be 1 */ +- MB_CHECK_ASSERT(mb_test_bit(i << 1, buddy2)); +- MB_CHECK_ASSERT(mb_test_bit((i << 1) + 1, buddy2)); +- +- for (j = 0; j < (1 << order); j++) { +- k = (i * (1 << order)) + j; +- MB_CHECK_ASSERT( +- !mb_test_bit(k, e4b->bd_bitmap)); +- } + count++; + } + MB_CHECK_ASSERT(e4b->bd_info->bb_counters[order] == count); +@@ -741,15 +750,21 @@ static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + fragments++; + fstart = i; + } +- continue; ++ } else { ++ fstart = -1; + } +- fstart = -1; +- /* check used bits only */ +- for (j = 0; j < e4b->bd_blkbits + 1; j++) { +- buddy2 = mb_find_buddy(e4b, j, &max2); +- k = i >> j; +- MB_CHECK_ASSERT(k < max2); +- MB_CHECK_ASSERT(mb_test_bit(k, buddy2)); ++ if (!(i & 1)) { ++ int in_use, zero_bit_count = 0; ++ ++ in_use = mb_test_bit(i, buddy) || mb_test_bit(i + 1, buddy); ++ for (j = 1; j < e4b->bd_blkbits + 2; j++) { ++ buddy2 = mb_find_buddy(e4b, j, &max2); ++ k = i >> j; ++ MB_CHECK_ASSERT(k < max2); ++ if (!mb_test_bit(k, buddy2)) ++ zero_bit_count++; ++ } ++ MB_CHECK_ASSERT(zero_bit_count == !in_use); + } + } + MB_CHECK_ASSERT(!EXT4_MB_GRP_NEED_INIT(e4b->bd_info)); +-- +2.51.0 + diff --git a/queue-6.6/ext4-remove-unused-return-value-of-__mb_check_buddy.patch b/queue-6.6/ext4-remove-unused-return-value-of-__mb_check_buddy.patch new file mode 100644 index 0000000000..16192f522d --- /dev/null +++ b/queue-6.6/ext4-remove-unused-return-value-of-__mb_check_buddy.patch @@ -0,0 +1,63 @@ +From 7acbb5bcb6dd0c2b54951f83703c2ce11a35284f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 5 Jan 2024 17:20:54 +0800 +Subject: ext4: remove unused return value of __mb_check_buddy + +From: Kemeng Shi + +[ Upstream commit 133de5a0d8f8e32b34feaa8beae7a189482f1856 ] + +Remove unused return value of __mb_check_buddy. + +Signed-off-by: Kemeng Shi +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/20240105092102.496631-2-shikemeng@huaweicloud.com +Signed-off-by: Theodore Ts'o +Stable-dep-of: d9ee3ff810f1 ("ext4: improve integrity checking in __mb_check_buddy by enhancing order-0 validation") +Signed-off-by: Sasha Levin +--- + fs/ext4/mballoc.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c +index c5f642096ab4e..9721ae0ff92ed 100644 +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -676,7 +676,7 @@ do { \ + } \ + } while (0) + +-static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, ++static void __mb_check_buddy(struct ext4_buddy *e4b, char *file, + const char *function, int line) + { + struct super_block *sb = e4b->bd_sb; +@@ -695,7 +695,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + void *buddy2; + + if (e4b->bd_info->bb_check_counter++ % 10) +- return 0; ++ return; + + while (order > 1) { + buddy = mb_find_buddy(e4b, order, &max); +@@ -757,7 +757,7 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + + grp = ext4_get_group_info(sb, e4b->bd_group); + if (!grp) +- return NULL; ++ return; + list_for_each(cur, &grp->bb_prealloc_list) { + ext4_group_t groupnr; + struct ext4_prealloc_space *pa; +@@ -767,7 +767,6 @@ static int __mb_check_buddy(struct ext4_buddy *e4b, char *file, + for (i = 0; i < pa->pa_len; i++) + MB_CHECK_ASSERT(mb_test_bit(k + i, buddy)); + } +- return 0; + } + #undef MB_CHECK_ASSERT + #define mb_check_buddy(e4b) __mb_check_buddy(e4b, \ +-- +2.51.0 + diff --git a/queue-6.6/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch b/queue-6.6/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch new file mode 100644 index 0000000000..7f93d18648 --- /dev/null +++ b/queue-6.6/fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch @@ -0,0 +1,46 @@ +From f3508b282b83b03dd5b20aa401907401b262b5d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 09:25:44 +0530 +Subject: fbdev: ssd1307fb: fix potential page leak in ssd1307fb_probe() + +From: Abdun Nihaal + +[ Upstream commit 164312662ae9764b83b84d97afb25c42eb2be473 ] + +The page allocated for vmem using __get_free_pages() is not freed on the +error paths after it. Fix that by adding a corresponding __free_pages() +call to the error path. + +Fixes: facd94bc458a ("fbdev: ssd1307fb: Allocate page aligned video memory.") +Signed-off-by: Abdun Nihaal +Signed-off-by: Helge Deller +Signed-off-by: Sasha Levin +--- + drivers/video/fbdev/ssd1307fb.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c +index 1a4f90ea7d5a8..bf8ec4861b45c 100644 +--- a/drivers/video/fbdev/ssd1307fb.c ++++ b/drivers/video/fbdev/ssd1307fb.c +@@ -688,7 +688,7 @@ static int ssd1307fb_probe(struct i2c_client *client) + if (!ssd1307fb_defio) { + dev_err(dev, "Couldn't allocate deferred io.\n"); + ret = -ENOMEM; +- goto fb_alloc_error; ++ goto fb_defio_error; + } + + ssd1307fb_defio->delay = HZ / refreshrate; +@@ -766,6 +766,8 @@ static int ssd1307fb_probe(struct i2c_client *client) + regulator_disable(par->vbat_reg); + reset_oled_error: + fb_deferred_io_cleanup(info); ++fb_defio_error: ++ __free_pages(vmem, get_order(vmem_size)); + fb_alloc_error: + framebuffer_release(info); + return ret; +-- +2.51.0 + diff --git a/queue-6.6/firmware-imx-scu-irq-fix-of-node-leak-in.patch b/queue-6.6/firmware-imx-scu-irq-fix-of-node-leak-in.patch new file mode 100644 index 0000000000..d2a8bc1139 --- /dev/null +++ b/queue-6.6/firmware-imx-scu-irq-fix-of-node-leak-in.patch @@ -0,0 +1,41 @@ +From 356df52db38ba7d7ab3ad6c50b3b8ac6d802a0b0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:56:24 +0800 +Subject: firmware: imx: scu-irq: fix OF node leak in + +From: Peng Fan + +[ Upstream commit ee67247843a2b62d1473cfa4df300e69b5190ccf ] + +imx_scu_enable_general_irq_channel() calls of_parse_phandle_with_args(), +but does not release the OF node reference. Add a of_node_put() call +to release the reference. + +Fixes: 851826c7566e ("firmware: imx: enable imx scu general irq function") +Reviewed-by: Frank Li +Signed-off-by: Peng Fan +Signed-off-by: Shawn Guo +Signed-off-by: Sasha Levin +--- + drivers/firmware/imx/imx-scu-irq.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/firmware/imx/imx-scu-irq.c b/drivers/firmware/imx/imx-scu-irq.c +index 6125cccc9ba79..f2b902e95b738 100644 +--- a/drivers/firmware/imx/imx-scu-irq.c ++++ b/drivers/firmware/imx/imx-scu-irq.c +@@ -226,8 +226,10 @@ int imx_scu_enable_general_irq_channel(struct device *dev) + INIT_WORK(&imx_sc_irq_work, imx_scu_irq_work_handler); + + if (!of_parse_phandle_with_args(dev->of_node, "mboxes", +- "#mbox-cells", 0, &spec)) ++ "#mbox-cells", 0, &spec)) { + i = of_alias_get_id(spec.np, "mu"); ++ of_node_put(spec.np); ++ } + + /* use mu1 as general mu irq channel if failed */ + if (i < 0) +-- +2.51.0 + diff --git a/queue-6.6/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch b/queue-6.6/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch new file mode 100644 index 0000000000..441819b95e --- /dev/null +++ b/queue-6.6/firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch @@ -0,0 +1,40 @@ +From 3f01b8fe5f3bff30e380b320185691dbd7b49eec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 12:58:13 -0600 +Subject: firmware: stratix10-svc: fix make htmldocs warning for stratix10_svc + +From: Dinh Nguyen + +[ Upstream commit 377441d53a2df61b105e823b335010cd4f1a6e56 ] + +Fix this warning that was generated from "make htmldocs": + +WARNING: drivers/firmware/stratix10-svc.c:58 struct member 'intel_svc_fcs' +not described in 'stratix10_svc' + +Fixes: e6281c26674e ("firmware: stratix10-svc: Add support for FCS") +Reported-by: Stephen Rothwell +Closes: https://lore.kernel.org/linux-next/20251106145941.37920e97@canb.auug.org.au/ +Signed-off-by: Dinh Nguyen +Link: https://patch.msgid.link/20251114185815.358423-1-dinguyen@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/firmware/stratix10-svc.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/firmware/stratix10-svc.c b/drivers/firmware/stratix10-svc.c +index 766ced12345c3..a133ac5fb0373 100644 +--- a/drivers/firmware/stratix10-svc.c ++++ b/drivers/firmware/stratix10-svc.c +@@ -52,6 +52,7 @@ struct stratix10_svc_chan; + /** + * struct stratix10_svc - svc private data + * @stratix10_svc_rsu: pointer to stratix10 RSU device ++ * @intel_svc_fcs: pointer to the FCS device + */ + struct stratix10_svc { + struct platform_device *stratix10_svc_rsu; +-- +2.51.0 + diff --git a/queue-6.6/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch b/queue-6.6/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch new file mode 100644 index 0000000000..9e01e92d1e --- /dev/null +++ b/queue-6.6/fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch @@ -0,0 +1,104 @@ +From f9a43d443ab1375218666f2829360101d18d21e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 2 Nov 2025 23:56:30 +0000 +Subject: fs/9p: Don't open remote file with APPEND mode when writeback cache + is used + +From: Tingmao Wang + +[ Upstream commit a63dd8fd137933551bfd9aeeeaa942f04c7aad65 ] + +When page cache is used, writebacks are done on a page granularity, and it +is expected that the underlying filesystem (such as v9fs) should respect +the write position. However, currently v9fs will passthrough O_APPEND to +the server even on cached mode. This causes data corruption if a sync or +fstat gets between two writes to the same file. + +This patch removes the APPEND flag from the open request we send to the +server when writeback caching is involved. I believe keeping server-side +APPEND is probably fine for uncached mode (even if two fds are opened, one +without O_APPEND and one with it, this should still be fine since they +would use separate fid for the writes). + +Signed-off-by: Tingmao Wang +Fixes: 4eb3117888a9 ("fs/9p: Rework cache modes and add new options to Documentation") +Message-ID: <20251102235631.8724-1-m@maowtm.org> +Signed-off-by: Dominique Martinet +Signed-off-by: Sasha Levin +--- + fs/9p/vfs_file.c | 11 ++++++++--- + fs/9p/vfs_inode.c | 3 +-- + fs/9p/vfs_inode_dotl.c | 2 +- + 3 files changed, 10 insertions(+), 6 deletions(-) + +diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c +index 8566ddad49ad5..655e7bf602f1e 100644 +--- a/fs/9p/vfs_file.c ++++ b/fs/9p/vfs_file.c +@@ -43,14 +43,18 @@ int v9fs_file_open(struct inode *inode, struct file *file) + struct v9fs_session_info *v9ses; + struct p9_fid *fid; + int omode; ++ int o_append; + + p9_debug(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, file); + v9ses = v9fs_inode2v9ses(inode); +- if (v9fs_proto_dotl(v9ses)) ++ if (v9fs_proto_dotl(v9ses)) { + omode = v9fs_open_to_dotl_flags(file->f_flags); +- else ++ o_append = P9_DOTL_APPEND; ++ } else { + omode = v9fs_uflags2omode(file->f_flags, + v9fs_proto_dotu(v9ses)); ++ o_append = P9_OAPPEND; ++ } + fid = file->private_data; + if (!fid) { + fid = v9fs_fid_clone(file_dentry(file)); +@@ -58,9 +62,10 @@ int v9fs_file_open(struct inode *inode, struct file *file) + return PTR_ERR(fid); + + if ((v9ses->cache & CACHE_WRITEBACK) && (omode & P9_OWRITE)) { +- int writeback_omode = (omode & ~P9_OWRITE) | P9_ORDWR; ++ int writeback_omode = (omode & ~(P9_OWRITE | o_append)) | P9_ORDWR; + + p9_debug(P9_DEBUG_CACHE, "write-only file with writeback enabled, try opening O_RDWR\n"); ++ + err = p9_client_open(fid, writeback_omode); + if (err < 0) { + p9_debug(P9_DEBUG_CACHE, "could not open O_RDWR, disabling caches\n"); +diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c +index aba0625de48ae..e084caf467d10 100644 +--- a/fs/9p/vfs_inode.c ++++ b/fs/9p/vfs_inode.c +@@ -824,7 +824,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, + p9_omode = v9fs_uflags2omode(flags, v9fs_proto_dotu(v9ses)); + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_OAPPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +@@ -1458,4 +1458,3 @@ static const struct inode_operations v9fs_symlink_inode_operations = { + .getattr = v9fs_vfs_getattr, + .setattr = v9fs_vfs_setattr, + }; +- +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index 91bcee2ab3c49..96e791c2b7b44 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -288,7 +288,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, + } + + if ((v9ses->cache & CACHE_WRITEBACK) && (p9_omode & P9_OWRITE)) { +- p9_omode = (p9_omode & ~P9_OWRITE) | P9_ORDWR; ++ p9_omode = (p9_omode & ~(P9_OWRITE | P9_DOTL_APPEND)) | P9_ORDWR; + p9_debug(P9_DEBUG_CACHE, + "write-only file with writeback enabled, creating w/ O_RDWR\n"); + } +-- +2.51.0 + diff --git a/queue-6.6/fs-ntfs3-out1-also-needs-to-put-mi.patch b/queue-6.6/fs-ntfs3-out1-also-needs-to-put-mi.patch new file mode 100644 index 0000000000..d679b2f085 --- /dev/null +++ b/queue-6.6/fs-ntfs3-out1-also-needs-to-put-mi.patch @@ -0,0 +1,38 @@ +From a7c2fd849642a6736fb9c01e15964588141418bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:13:56 +0800 +Subject: fs/ntfs3: out1 also needs to put mi + +From: Edward Adam Davis + +[ Upstream commit 4d78d1173a653acdaf7500a32b8dc530ca4ad075 ] + +After ntfs_look_free_mft() executes successfully, all subsequent code +that fails to execute must put mi. + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 5c45fec832b00..6ff10042a15f2 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -1067,9 +1067,9 @@ static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le, + + out2: + ni_remove_mi(ni, mi); +- mi_put(mi); + + out1: ++ mi_put(mi); + ntfs_mark_rec_free(sbi, rno, is_mft); + + out: +-- +2.51.0 + diff --git a/queue-6.6/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch b/queue-6.6/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch new file mode 100644 index 0000000000..c309a71a69 --- /dev/null +++ b/queue-6.6/fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch @@ -0,0 +1,59 @@ +From 35c3b3c9cc4bdddc566895207c0ce907ea7e34a6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 11 Nov 2025 19:05:42 +0800 +Subject: fs/ntfs3: Prevent memory leaks in add sub record + +From: Edward Adam Davis + +[ Upstream commit ccc4e86d1c24260c18ae94541198c3711c140da6 ] + +If a rb node with the same ino already exists in the rb tree, the newly +alloced mft_inode in ni_add_subrecord() will not have its memory cleaned +up, which leads to the memory leak issue reported by syzbot. + +The best option to avoid this issue is to put the newly alloced mft node +when a rb node with the same ino already exists in the rb tree and return +the rb node found in the rb tree to the parent layer. + +syzbot reported: +BUG: memory leak +unreferenced object 0xffff888110bef280 (size 128): + backtrace (crc 126a088f): + ni_add_subrecord+0x31/0x180 fs/ntfs3/frecord.c:317 + ntfs_look_free_mft+0xf0/0x790 fs/ntfs3/fsntfs.c:715 + +BUG: memory leak +unreferenced object 0xffff888109093400 (size 1024): + backtrace (crc 7197c55e): + mi_init+0x2b/0x50 fs/ntfs3/record.c:105 + mi_format_new+0x40/0x220 fs/ntfs3/record.c:422 + +Fixes: 4342306f0f0d ("fs/ntfs3: Add file operations and implementation") +Reported-by: syzbot+3932ccb896e06f7414c9@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/frecord.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c +index 6ff10042a15f2..18e41faef8e68 100644 +--- a/fs/ntfs3/frecord.c ++++ b/fs/ntfs3/frecord.c +@@ -378,8 +378,10 @@ bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi) + + mi_get_ref(&ni->mi, &m->mrec->parent_ref); + +- ni_add_mi(ni, m); +- *mi = m; ++ *mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node); ++ if (*mi != m) ++ mi_put(m); ++ + return true; + } + +-- +2.51.0 + diff --git a/queue-6.6/gpu-host1x-fix-race-in-syncpt-alloc-free.patch b/queue-6.6/gpu-host1x-fix-race-in-syncpt-alloc-free.patch new file mode 100644 index 0000000000..95106f104d --- /dev/null +++ b/queue-6.6/gpu-host1x-fix-race-in-syncpt-alloc-free.patch @@ -0,0 +1,58 @@ +From 5e070c66146426e4673b5a3c0498184ccaf43706 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Jul 2025 18:17:39 +0900 +Subject: gpu: host1x: Fix race in syncpt alloc/free + +From: Mainak Sen + +[ Upstream commit c7d393267c497502fa737607f435f05dfe6e3d9b ] + +Fix race condition between host1x_syncpt_alloc() +and host1x_syncpt_put() by using kref_put_mutex() +instead of kref_put() + manual mutex locking. + +This ensures no thread can acquire the +syncpt_mutex after the refcount drops to zero +but before syncpt_release acquires it. +This prevents races where syncpoints could +be allocated while still being cleaned up +from a previous release. + +Remove explicit mutex locking in syncpt_release +as kref_put_mutex() handles this atomically. + +Signed-off-by: Mainak Sen +Fixes: f5ba33fb9690 ("gpu: host1x: Reserve VBLANK syncpoints at initialization") +Signed-off-by: Mikko Perttunen +Signed-off-by: Thierry Reding +Link: https://lore.kernel.org/r/20250707-host1x-syncpt-race-fix-v1-1-28b0776e70bc@nvidia.com +Signed-off-by: Sasha Levin +--- + drivers/gpu/host1x/syncpt.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c +index f63d14a57a1d9..acc7d82e0585e 100644 +--- a/drivers/gpu/host1x/syncpt.c ++++ b/drivers/gpu/host1x/syncpt.c +@@ -345,8 +345,6 @@ static void syncpt_release(struct kref *ref) + + sp->locked = false; + +- mutex_lock(&sp->host->syncpt_mutex); +- + host1x_syncpt_base_free(sp->base); + kfree(sp->name); + sp->base = NULL; +@@ -369,7 +367,7 @@ void host1x_syncpt_put(struct host1x_syncpt *sp) + if (!sp) + return; + +- kref_put(&sp->ref, syncpt_release); ++ kref_put_mutex(&sp->ref, syncpt_release, &sp->host->syncpt_mutex); + } + EXPORT_SYMBOL(host1x_syncpt_put); + +-- +2.51.0 + diff --git a/queue-6.6/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch b/queue-6.6/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch new file mode 100644 index 0000000000..7a33f986e5 --- /dev/null +++ b/queue-6.6/hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch @@ -0,0 +1,59 @@ +From ce84ebf68593dad865b359752712f4d4ed275e52 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 19:30:58 +0000 +Subject: HID: logitech-hidpp: Do not assume FAP in hidpp_send_message_sync() + +From: Mavroudis Chatzilazaridis + +[ Upstream commit aba7963544d47d82cdf36602a6678a093af0299d ] + +Currently, hidpp_send_message_sync() retries sending the message when the +device returns a busy error code, specifically HIDPP20_ERROR_BUSY, which +has a different meaning under RAP. This ends up being a problem because +this function is used for both FAP and RAP messages. + +This issue is not noticeable on older receivers with unreachable devices +since they return HIDPP_ERROR_RESOURCE_ERROR (0x09), which is not equal to +HIDPP20_ERROR_BUSY (0x08). + +However, newer receivers return HIDPP_ERROR_UNKNOWN_DEVICE (0x08) which +happens to equal to HIDPP20_ERROR_BUSY, causing unnecessary retries when +the device is not actually busy. + +This is resolved by checking if the error response is FAP or RAP and +picking the respective ERROR_BUSY code. + +Fixes: 60165ab774cb ("HID: logitech-hidpp: rework one more time the retries attempts") +Signed-off-by: Mavroudis Chatzilazaridis +Tested-by: Stuart Hayhurst +Signed-off-by: Jiri Kosina +Signed-off-by: Sasha Levin +--- + drivers/hid/hid-logitech-hidpp.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c +index 3a2c1e48aba20..5a2fe703cf57b 100644 +--- a/drivers/hid/hid-logitech-hidpp.c ++++ b/drivers/hid/hid-logitech-hidpp.c +@@ -351,10 +351,15 @@ static int hidpp_send_message_sync(struct hidpp_device *hidpp, + + do { + ret = __do_hidpp_send_message_sync(hidpp, message, response); +- if (ret != HIDPP20_ERROR_BUSY) ++ if (response->report_id == REPORT_ID_HIDPP_SHORT && ++ ret != HIDPP_ERROR_BUSY) ++ break; ++ if ((response->report_id == REPORT_ID_HIDPP_LONG || ++ response->report_id == REPORT_ID_HIDPP_VERY_LONG) && ++ ret != HIDPP20_ERROR_BUSY) + break; + +- dbg_hid("%s:got busy hidpp 2.0 error %02X, retrying\n", __func__, ret); ++ dbg_hid("%s:got busy hidpp error %02X, retrying\n", __func__, ret); + } while (--max_retries); + + mutex_unlock(&hidpp->send_mutex); +-- +2.51.0 + diff --git a/queue-6.6/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch b/queue-6.6/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch new file mode 100644 index 0000000000..79017f9f22 --- /dev/null +++ b/queue-6.6/hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch @@ -0,0 +1,54 @@ +From afcc243a0e995e5c27db0e2d3829ed01e69de7c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 00:26:02 +0800 +Subject: hwmon: sy7636a: Fix regulator_enable resource leak on error path + +From: Haotian Zhang + +[ Upstream commit 2f88425ef590b7fcc2324334b342e048edc144a9 ] + +In sy7636a_sensor_probe(), regulator_enable() is called but if +devm_hwmon_device_register_with_info() fails, the function returns +without calling regulator_disable(), leaving the regulator enabled +and leaking the reference count. + +Switch to devm_regulator_get_enable() to automatically +manage the regulator resource. + +Fixes: de34a4053250 ("hwmon: sy7636a: Add temperature driver for sy7636a") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Link: https://lore.kernel.org/r/20251126162602.2086-1-vulab@iscas.ac.cn +Signed-off-by: Guenter Roeck +Signed-off-by: Sasha Levin +--- + drivers/hwmon/sy7636a-hwmon.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/hwmon/sy7636a-hwmon.c b/drivers/hwmon/sy7636a-hwmon.c +index a12fc0ce70e76..d51daaf63d632 100644 +--- a/drivers/hwmon/sy7636a-hwmon.c ++++ b/drivers/hwmon/sy7636a-hwmon.c +@@ -66,18 +66,13 @@ static const struct hwmon_chip_info sy7636a_chip_info = { + static int sy7636a_sensor_probe(struct platform_device *pdev) + { + struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); +- struct regulator *regulator; + struct device *hwmon_dev; + int err; + + if (!regmap) + return -EPROBE_DEFER; + +- regulator = devm_regulator_get(&pdev->dev, "vcom"); +- if (IS_ERR(regulator)) +- return PTR_ERR(regulator); +- +- err = regulator_enable(regulator); ++ err = devm_regulator_get_enable(&pdev->dev, "vcom"); + if (err) + return err; + +-- +2.51.0 + diff --git a/queue-6.6/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch b/queue-6.6/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch new file mode 100644 index 0000000000..5d95246efe --- /dev/null +++ b/queue-6.6/i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch @@ -0,0 +1,59 @@ +From 51770327d0a024f0b3ac1178f2c9697d9e755f8d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 16 Oct 2025 10:38:13 -0400 +Subject: i3c: fix refcount inconsistency in i3c_master_register + +From: Frank Li + +[ Upstream commit 9d4f219807d5ac11fb1d596e4ddb09336b040067 ] + +In `i3c_master_register`, a possible refcount inconsistency has been +identified, causing possible resource leak. + +Function `of_node_get` increases the refcount of `parent->of_node`. If +function `i3c_bus_init` fails, the function returns immediately without +a corresponding decrease, resulting in an inconsistent refcounter. + +Move call i3c_bus_init() after device_initialize() to let callback +i3c_masterdev_release() release of_node. + +Reported-by: Shuhao Fu +Closes: https://lore.kernel.org/linux-i3c/aO2tjp_FsV_WohPG@osx.local/T/#m2c05a982beeb14e7bf039c1d8db856734bf234c7 +Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") +Signed-off-by: Frank Li +Link: https://patch.msgid.link/20251016143814.2551256-1-Frank.Li@nxp.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index 29e591bcc0646..060f70e4d52d7 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2768,10 +2768,6 @@ int i3c_master_register(struct i3c_master_controller *master, + INIT_LIST_HEAD(&master->boardinfo.i2c); + INIT_LIST_HEAD(&master->boardinfo.i3c); + +- ret = i3c_bus_init(i3cbus, master->dev.of_node); +- if (ret) +- return ret; +- + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + +@@ -2779,6 +2775,10 @@ int i3c_master_register(struct i3c_master_controller *master, + master->dev.coherent_dma_mask = parent->coherent_dma_mask; + master->dev.dma_parms = parent->dma_parms; + ++ ret = i3c_bus_init(i3cbus, master->dev.of_node); ++ if (ret) ++ goto err_put_dev; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.6/i3c-master-inherit-dma-masks-and-parameters-from-par.patch b/queue-6.6/i3c-master-inherit-dma-masks-and-parameters-from-par.patch new file mode 100644 index 0000000000..013506be6d --- /dev/null +++ b/queue-6.6/i3c-master-inherit-dma-masks-and-parameters-from-par.patch @@ -0,0 +1,40 @@ +From cbfe7f9fdc410c136a6f68c49132fd1125102fdb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Sep 2023 08:56:53 +0300 +Subject: i3c: master: Inherit DMA masks and parameters from parent device + +From: Jarkko Nikula + +[ Upstream commit 0c35691551387e060e6ae7a6652b4101270c73cf ] + +Copy the DMA masks and parameters for an I3C master device from parent +device so that the master device has them set for the DMA buffer and +mapping API. + +Signed-off-by: Jarkko Nikula +Link: https://lore.kernel.org/r/20230921055704.1087277-2-jarkko.nikula@linux.intel.com +Signed-off-by: Alexandre Belloni +Stable-dep-of: 9d4f219807d5 ("i3c: fix refcount inconsistency in i3c_master_register") +Signed-off-by: Sasha Levin +--- + drivers/i3c/master.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c +index b6995e767850b..29e591bcc0646 100644 +--- a/drivers/i3c/master.c ++++ b/drivers/i3c/master.c +@@ -2775,6 +2775,10 @@ int i3c_master_register(struct i3c_master_controller *master, + device_initialize(&master->dev); + dev_set_name(&master->dev, "i3c-%d", i3cbus->id); + ++ master->dev.dma_mask = parent->dma_mask; ++ master->dev.coherent_dma_mask = parent->coherent_dma_mask; ++ master->dev.dma_parms = parent->dma_parms; ++ + ret = of_populate_i3c_bus(master); + if (ret) + goto err_put_dev; +-- +2.51.0 + diff --git a/queue-6.6/i3c-master-svc-prevent-incomplete-ibi-transaction.patch b/queue-6.6/i3c-master-svc-prevent-incomplete-ibi-transaction.patch new file mode 100644 index 0000000000..e512516210 --- /dev/null +++ b/queue-6.6/i3c-master-svc-prevent-incomplete-ibi-transaction.patch @@ -0,0 +1,69 @@ +From 6e3a6d2d10f0f8e8f120b8513b8b3d439f044499 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:47:15 +0800 +Subject: i3c: master: svc: Prevent incomplete IBI transaction + +From: Stanley Chu + +[ Upstream commit 3a36273e5a07dda0ccec193800f3b78c3c0380af ] + +If no free IBI slot is available, svc_i3c_master_handle_ibi returns +immediately. This causes the STOP condition to be missed because the +EmitStop request is sent when the transfer is not complete. To resolve +this, svc_i3c_master_handle_ibi must wait for the transfer to complete +before returning. + +Fixes: dd3c52846d59 ("i3c: master: svc: Add Silvaco I3C master driver") +Signed-off-by: Stanley Chu +Reviewed-by: Frank Li +Reviewed-by: Miquel Raynal +Link: https://patch.msgid.link/20251027034715.708243-1-yschu@nuvoton.com +Signed-off-by: Alexandre Belloni +Signed-off-by: Sasha Levin +--- + drivers/i3c/master/svc-i3c-master.c | 22 ++++++++++++++-------- + 1 file changed, 14 insertions(+), 8 deletions(-) + +diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c +index 277884b5e1ca4..3222b8f56a926 100644 +--- a/drivers/i3c/master/svc-i3c-master.c ++++ b/drivers/i3c/master/svc-i3c-master.c +@@ -358,21 +358,27 @@ static int svc_i3c_master_handle_ibi(struct svc_i3c_master *master, + int ret, val; + u8 *buf; + +- slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); +- if (!slot) +- return -ENOSPC; +- +- slot->len = 0; +- buf = slot->data; +- ++ /* ++ * Wait for transfer to complete before returning. Otherwise, the EmitStop ++ * request might be sent when the transfer is not complete. ++ */ + ret = readl_relaxed_poll_timeout(master->regs + SVC_I3C_MSTATUS, val, + SVC_I3C_MSTATUS_COMPLETE(val), 0, 1000); + if (ret) { + dev_err(master->dev, "Timeout when polling for COMPLETE\n"); +- i3c_generic_ibi_recycle_slot(data->ibi_pool, slot); + return ret; + } + ++ slot = i3c_generic_ibi_get_free_slot(data->ibi_pool); ++ if (!slot) { ++ dev_dbg(master->dev, "No free ibi slot, drop the data\n"); ++ writel(SVC_I3C_MDATACTRL_FLUSHRB, master->regs + SVC_I3C_MDATACTRL); ++ return -ENOSPC; ++ } ++ ++ slot->len = 0; ++ buf = slot->data; ++ + while (SVC_I3C_MSTATUS_RXPEND(readl(master->regs + SVC_I3C_MSTATUS)) && + slot->len < SVC_I3C_FIFO_SIZE) { + mdatactrl = readl(master->regs + SVC_I3C_MDATACTRL); +-- +2.51.0 + diff --git a/queue-6.6/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch b/queue-6.6/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch new file mode 100644 index 0000000000..52979907cf --- /dev/null +++ b/queue-6.6/iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch @@ -0,0 +1,37 @@ +From c63f838553c51429e90c3da0e4f72641a71f6770 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 18:42:54 +0200 +Subject: iio: imu: st_lsm6dsx: Fix measurement unit for odr struct member + +From: Francesco Lavra + +[ Upstream commit c6d702f2b77194b62fb2098c63bb7f2a87da142d ] + +The `odr` field in struct st_lsm6dsx_sensor contains a data rate +value expressed in mHz, not in Hz. + +Fixes: f8710f0357bc3 ("iio: imu: st_lsm6dsx: express odr in mHZ") +Signed-off-by: Francesco Lavra +Acked-by: Lorenzo Bianconi +Signed-off-by: Jonathan Cameron +Signed-off-by: Sasha Levin +--- + drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +index 35325d2e1ce6c..33b5c660103e4 100644 +--- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h ++++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +@@ -381,7 +381,7 @@ enum st_lsm6dsx_fifo_mode { + * @id: Sensor identifier. + * @hw: Pointer to instance of struct st_lsm6dsx_hw. + * @gain: Configured sensor sensitivity. +- * @odr: Output data rate of the sensor [Hz]. ++ * @odr: Output data rate of the sensor [mHz]. + * @samples_to_discard: Number of samples to discard for filters settling time. + * @watermark: Sensor watermark level. + * @decimator: Sensor decimation factor. +-- +2.51.0 + diff --git a/queue-6.6/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch b/queue-6.6/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch new file mode 100644 index 0000000000..14e3fcd974 --- /dev/null +++ b/queue-6.6/ima-handle-error-code-returned-by-ima_filter_rule_ma.patch @@ -0,0 +1,74 @@ +From f4704044570f527ba459afd9942b5ec504ef0f33 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 15:18:05 +0800 +Subject: ima: Handle error code returned by ima_filter_rule_match() + +From: Zhao Yipeng + +[ Upstream commit 738c9738e690f5cea24a3ad6fd2d9a323cf614f6 ] + +In ima_match_rules(), if ima_filter_rule_match() returns -ENOENT due to +the rule being NULL, the function incorrectly skips the 'if (!rc)' check +and sets 'result = true'. The LSM rule is considered a match, causing +extra files to be measured by IMA. + +This issue can be reproduced in the following scenario: +After unloading the SELinux policy module via 'semodule -d', if an IMA +measurement is triggered before ima_lsm_rules is updated, +in ima_match_rules(), the first call to ima_filter_rule_match() returns +-ESTALE. This causes the code to enter the 'if (rc == -ESTALE && +!rule_reinitialized)' block, perform ima_lsm_copy_rule() and retry. In +ima_lsm_copy_rule(), since the SELinux module has been removed, the rule +becomes NULL, and the second call to ima_filter_rule_match() returns +-ENOENT. This bypasses the 'if (!rc)' check and results in a false match. + +Call trace: + selinux_audit_rule_match+0x310/0x3b8 + security_audit_rule_match+0x60/0xa0 + ima_match_rules+0x2e4/0x4a0 + ima_match_policy+0x9c/0x1e8 + ima_get_action+0x48/0x60 + process_measurement+0xf8/0xa98 + ima_bprm_check+0x98/0xd8 + security_bprm_check+0x5c/0x78 + search_binary_handler+0x6c/0x318 + exec_binprm+0x58/0x1b8 + bprm_execve+0xb8/0x130 + do_execveat_common.isra.0+0x1a8/0x258 + __arm64_sys_execve+0x48/0x68 + invoke_syscall+0x50/0x128 + el0_svc_common.constprop.0+0xc8/0xf0 + do_el0_svc+0x24/0x38 + el0_svc+0x44/0x200 + el0t_64_sync_handler+0x100/0x130 + el0t_64_sync+0x3c8/0x3d0 + +Fix this by changing 'if (!rc)' to 'if (rc <= 0)' to ensure that error +codes like -ENOENT do not bypass the check and accidentally result in a +successful match. + +Fixes: 4af4662fa4a9d ("integrity: IMA policy") +Signed-off-by: Zhao Yipeng +Reviewed-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Sasha Levin +--- + security/integrity/ima/ima_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c +index f3f46c6186c08..afbf963cb7483 100644 +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -672,7 +672,7 @@ static bool ima_match_rules(struct ima_rule_entry *rule, + goto retry; + } + } +- if (!rc) { ++ if (rc <= 0) { + result = false; + goto out; + } +-- +2.51.0 + diff --git a/queue-6.6/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch b/queue-6.6/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch new file mode 100644 index 0000000000..828c633bff --- /dev/null +++ b/queue-6.6/inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch @@ -0,0 +1,94 @@ +From 93e578326e776d59990c8a4abf17a347cb4a79c1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:35 +0800 +Subject: inet: Avoid ehash lookup race in inet_ehash_insert() + +From: Xuanqiang Luo + +[ Upstream commit 1532ed0d0753c83e72595f785f82b48c28bbe5dc ] + +Since ehash lookups are lockless, if one CPU performs a lookup while +another concurrently deletes and inserts (removing reqsk and inserting sk), +the lookup may fail to find the socket, an RST may be sent. + +The call trace map is drawn as follows: + CPU 0 CPU 1 + ----- ----- + inet_ehash_insert() + spin_lock() + sk_nulls_del_node_init_rcu(osk) +__inet_lookup_established() + (lookup failed) + __sk_nulls_add_node_rcu(sk, list) + spin_unlock() + +As both deletion and insertion operate on the same ehash chain, this patch +introduces a new sk_nulls_replace_node_init_rcu() helper functions to +implement atomic replacement. + +Fixes: 5e0724d027f0 ("tcp/dccp: fix hashdance race for passive sessions") +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Jiayuan Chen +Signed-off-by: Xuanqiang Luo +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20251015020236.431822-3-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/sock.h | 13 +++++++++++++ + net/ipv4/inet_hashtables.c | 8 ++++++-- + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/include/net/sock.h b/include/net/sock.h +index f8e029cc48ccc..d516ed8050084 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -825,6 +825,19 @@ static inline bool sk_nulls_del_node_init_rcu(struct sock *sk) + return rc; + } + ++static inline bool sk_nulls_replace_node_init_rcu(struct sock *old, ++ struct sock *new) ++{ ++ if (sk_hashed(old)) { ++ hlist_nulls_replace_init_rcu(&old->sk_nulls_node, ++ &new->sk_nulls_node); ++ __sock_put(old); ++ return true; ++ } ++ ++ return false; ++} ++ + static inline void __sk_add_node(struct sock *sk, struct hlist_head *list) + { + hlist_add_head(&sk->sk_node, list); +diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c +index 60e81f6b1c6d4..7292f70176251 100644 +--- a/net/ipv4/inet_hashtables.c ++++ b/net/ipv4/inet_hashtables.c +@@ -676,8 +676,11 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + spin_lock(lock); + if (osk) { + WARN_ON_ONCE(sk->sk_hash != osk->sk_hash); +- ret = sk_nulls_del_node_init_rcu(osk); +- } else if (found_dup_sk) { ++ ret = sk_nulls_replace_node_init_rcu(osk, sk); ++ goto unlock; ++ } ++ ++ if (found_dup_sk) { + *found_dup_sk = inet_ehash_lookup_by_sk(sk, list); + if (*found_dup_sk) + ret = false; +@@ -686,6 +689,7 @@ bool inet_ehash_insert(struct sock *sk, struct sock *osk, bool *found_dup_sk) + if (ret) + __sk_nulls_add_node_rcu(sk, list); + ++unlock: + spin_unlock(lock); + + return ret; +-- +2.51.0 + diff --git a/queue-6.6/interconnect-debugfs-fix-incorrect-error-handling-fo.patch b/queue-6.6/interconnect-debugfs-fix-incorrect-error-handling-fo.patch new file mode 100644 index 0000000000..00b3553476 --- /dev/null +++ b/queue-6.6/interconnect-debugfs-fix-incorrect-error-handling-fo.patch @@ -0,0 +1,53 @@ +From 221fd6713d53f8289be61e19b055ee3f9c8bd613 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 23:14:47 +0800 +Subject: interconnect: debugfs: Fix incorrect error handling for NULL path + +From: Kuan-Wei Chiu + +[ Upstream commit 6bfe104fd0f94d0248af22c256ce725ee087157b ] + +The icc_commit_set() function, used by the debugfs interface, checks +the validity of the global cur_path pointer using IS_ERR_OR_NULL(). +However, in the specific case where cur_path is NULL, while +IS_ERR_OR_NULL(NULL) correctly evaluates to true, the subsequent call +to PTR_ERR(NULL) returns 0. + +This causes the function to return a success code (0) instead of an +error, misleading the user into believing their bandwidth request was +successfully committed when, in fact, no operation was performed. + +Fix this by adding an explicit check to return -EINVAL if cur_path is +NULL. This prevents silent failures and ensures that an invalid +operational sequence is immediately and clearly reported as an error. + +Fixes: 770c69f037c1 ("interconnect: Add debugfs test client") +Signed-off-by: Kuan-Wei Chiu +Link: https://lore.kernel.org/r/20251010151447.2289779-1-visitorckw@gmail.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/debugfs-client.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/interconnect/debugfs-client.c b/drivers/interconnect/debugfs-client.c +index bc3fd8a7b9eb4..778deeb4a7e8a 100644 +--- a/drivers/interconnect/debugfs-client.c ++++ b/drivers/interconnect/debugfs-client.c +@@ -117,7 +117,12 @@ static int icc_commit_set(void *data, u64 val) + + mutex_lock(&debugfs_lock); + +- if (IS_ERR_OR_NULL(cur_path)) { ++ if (!cur_path) { ++ ret = -EINVAL; ++ goto out; ++ } ++ ++ if (IS_ERR(cur_path)) { + ret = PTR_ERR(cur_path); + goto out; + } +-- +2.51.0 + diff --git a/queue-6.6/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch b/queue-6.6/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch new file mode 100644 index 0000000000..4a72695bdf --- /dev/null +++ b/queue-6.6/interconnect-qcom-msm8996-add-missing-link-to-slave_.patch @@ -0,0 +1,38 @@ +From 2020306557cad1c4d3c83fc1b6324ab6c7872289 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 2 Oct 2025 11:53:00 +0300 +Subject: interconnect: qcom: msm8996: add missing link to SLAVE_USB_HS + +From: Dmitry Baryshkov + +[ Upstream commit 8cf9b43f6b4d90e19a9341edefdd46842d4adb55 ] + +>From the initial submission the interconnect driver missed the link from +SNOC_PNOC to the USB 2 configuration space. Add missing link in order to +let the platform configure and utilize this path. + +Fixes: 7add937f5222 ("interconnect: qcom: Add MSM8996 interconnect provider driver") +Signed-off-by: Dmitry Baryshkov +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251002-fix-msm8996-icc-v1-1-a36a05d1f869@oss.qualcomm.com +Signed-off-by: Georgi Djakov +Signed-off-by: Sasha Levin +--- + drivers/interconnect/qcom/msm8996.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/interconnect/qcom/msm8996.c b/drivers/interconnect/qcom/msm8996.c +index 88683dfa468f6..84811fe32782f 100644 +--- a/drivers/interconnect/qcom/msm8996.c ++++ b/drivers/interconnect/qcom/msm8996.c +@@ -550,6 +550,7 @@ static struct qcom_icc_node mas_venus_vmem = { + static const u16 mas_snoc_pnoc_links[] = { + MSM8996_SLAVE_BLSP_1, + MSM8996_SLAVE_BLSP_2, ++ MSM8996_SLAVE_USB_HS, + MSM8996_SLAVE_SDCC_1, + MSM8996_SLAVE_SDCC_2, + MSM8996_SLAVE_SDCC_4, +-- +2.51.0 + diff --git a/queue-6.6/iomap-always-run-error-completions-in-user-context.patch b/queue-6.6/iomap-always-run-error-completions-in-user-context.patch new file mode 100644 index 0000000000..b88a4a8641 --- /dev/null +++ b/queue-6.6/iomap-always-run-error-completions-in-user-context.patch @@ -0,0 +1,51 @@ +From 8caf4ac60f8a1de2808eb3362b0561aa81d8e6f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 18:06:27 +0100 +Subject: iomap: always run error completions in user context + +From: Christoph Hellwig + +[ Upstream commit ddb4873286e03e193c5a3bebb5fc6fa820e9ee3a ] + +At least zonefs expects error completions to be able to sleep. Because +error completions aren't performance critical, just defer them to workqueue +context unconditionally. + +Fixes: 8dcc1a9d90c1 ("fs: New zonefs file system") +Signed-off-by: Christoph Hellwig +Link: https://patch.msgid.link/20251113170633.1453259-3-hch@lst.de +Reviewed-by: Jan Kara +Reviewed-by: Chaitanya Kulkarni +Signed-off-by: Christian Brauner +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index 1b0f06e7e58de..8158ab18e1ae8 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -172,7 +172,18 @@ static void iomap_dio_done(struct iomap_dio *dio) + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ return; ++ } ++ ++ /* ++ * Always run error completions in user context. These are not ++ * performance critical and some code relies on taking sleeping locks ++ * for error handling. ++ */ ++ if (dio->error) ++ dio->flags &= ~IOMAP_DIO_INLINE_COMP; ++ ++ if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); + } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { +-- +2.51.0 + diff --git a/queue-6.6/iomap-factor-out-a-iomap_dio_done-helper.patch b/queue-6.6/iomap-factor-out-a-iomap_dio_done-helper.patch new file mode 100644 index 0000000000..18e7f3bd79 --- /dev/null +++ b/queue-6.6/iomap-factor-out-a-iomap_dio_done-helper.patch @@ -0,0 +1,132 @@ +From 931d93c399035aaa70b75d06431c948d0eaa13d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Feb 2025 07:40:04 +0100 +Subject: iomap: factor out a iomap_dio_done helper + +From: Christoph Hellwig + +[ Upstream commit ae2f33a519af3730cacd1c787ebe1f7475df5ba8 ] + +Split out the struct iomap-dio level final completion from +iomap_dio_bio_end_io into a helper to clean up the code and make it +reusable. + +Signed-off-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20250206064035.2323428-7-hch@lst.de +Reviewed-by: "Darrick J. Wong" +Signed-off-by: Christian Brauner +Stable-dep-of: ddb4873286e0 ("iomap: always run error completions in user context") +Signed-off-by: Sasha Levin +--- + fs/iomap/direct-io.c | 76 ++++++++++++++++++++++---------------------- + 1 file changed, 38 insertions(+), 38 deletions(-) + +diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c +index bcd3f8cf5ea42..1b0f06e7e58de 100644 +--- a/fs/iomap/direct-io.c ++++ b/fs/iomap/direct-io.c +@@ -156,43 +156,31 @@ static inline void iomap_dio_set_error(struct iomap_dio *dio, int ret) + cmpxchg(&dio->error, 0, ret); + } + +-void iomap_dio_bio_end_io(struct bio *bio) ++/* ++ * Called when dio->ref reaches zero from an I/O completion. ++ */ ++static void iomap_dio_done(struct iomap_dio *dio) + { +- struct iomap_dio *dio = bio->bi_private; +- bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); + struct kiocb *iocb = dio->iocb; + +- if (bio->bi_status) +- iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); +- if (!atomic_dec_and_test(&dio->ref)) +- goto release_bio; +- +- /* +- * Synchronous dio, task itself will handle any completion work +- * that needs after IO. All we need to do is wake the task. +- */ + if (dio->wait_for_completion) { ++ /* ++ * Synchronous I/O, task itself will handle any completion work ++ * that needs after IO. All we need to do is wake the task. ++ */ + struct task_struct *waiter = dio->submit.waiter; + + WRITE_ONCE(dio->submit.waiter, NULL); + blk_wake_io_task(waiter); +- goto release_bio; +- } +- +- /* +- * Flagged with IOMAP_DIO_INLINE_COMP, we can complete it inline +- */ +- if (dio->flags & IOMAP_DIO_INLINE_COMP) { ++ } else if (dio->flags & IOMAP_DIO_INLINE_COMP) { + WRITE_ONCE(iocb->private, NULL); + iomap_dio_complete_work(&dio->aio.work); +- goto release_bio; +- } +- +- /* +- * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then schedule +- * our completion that way to avoid an async punt to a workqueue. +- */ +- if (dio->flags & IOMAP_DIO_CALLER_COMP) { ++ } else if (dio->flags & IOMAP_DIO_CALLER_COMP) { ++ /* ++ * If this dio is flagged with IOMAP_DIO_CALLER_COMP, then ++ * schedule our completion that way to avoid an async punt to a ++ * workqueue. ++ */ + /* only polled IO cares about private cleared */ + iocb->private = dio; + iocb->dio_complete = iomap_dio_deferred_complete; +@@ -210,19 +198,31 @@ void iomap_dio_bio_end_io(struct bio *bio) + * issuer. + */ + iocb->ki_complete(iocb, 0); +- goto release_bio; ++ } else { ++ struct inode *inode = file_inode(iocb->ki_filp); ++ ++ /* ++ * Async DIO completion that requires filesystem level ++ * completion work gets punted to a work queue to complete as ++ * the operation may require more IO to be issued to finalise ++ * filesystem metadata changes or guarantee data integrity. ++ */ ++ INIT_WORK(&dio->aio.work, iomap_dio_complete_work); ++ queue_work(inode->i_sb->s_dio_done_wq, &dio->aio.work); + } ++} ++ ++void iomap_dio_bio_end_io(struct bio *bio) ++{ ++ struct iomap_dio *dio = bio->bi_private; ++ bool should_dirty = (dio->flags & IOMAP_DIO_DIRTY); ++ ++ if (bio->bi_status) ++ iomap_dio_set_error(dio, blk_status_to_errno(bio->bi_status)); ++ ++ if (atomic_dec_and_test(&dio->ref)) ++ iomap_dio_done(dio); + +- /* +- * Async DIO completion that requires filesystem level completion work +- * gets punted to a work queue to complete as the operation may require +- * more IO to be issued to finalise filesystem metadata changes or +- * guarantee data integrity. +- */ +- INIT_WORK(&dio->aio.work, iomap_dio_complete_work); +- queue_work(file_inode(iocb->ki_filp)->i_sb->s_dio_done_wq, +- &dio->aio.work); +-release_bio: + if (should_dirty) { + bio_check_pages_dirty(bio); + } else { +-- +2.51.0 + diff --git a/queue-6.6/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch b/queue-6.6/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch new file mode 100644 index 0000000000..73cb767c1e --- /dev/null +++ b/queue-6.6/iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch @@ -0,0 +1,85 @@ +From 08e7e5bde5f1857816359c3f324a4a1ce5cdc55c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 21 Aug 2025 10:33:53 +0200 +Subject: iommu/arm-smmu-qcom: Enable use of all SMR groups when running + bare-metal + +From: Stephan Gerhold + +[ Upstream commit 5583a55e074b33ccd88ac0542fd7cd656a7e2c8c ] + +Some platforms (e.g. SC8280XP and X1E) support more than 128 stream +matching groups. This is more than what is defined as maximum by the ARM +SMMU architecture specification. Commit 122611347326 ("iommu/arm-smmu-qcom: +Limit the SMR groups to 128") disabled use of the additional groups because +they don't exhibit the same behavior as the architecture supported ones. + +It seems like this is just another quirk of the hypervisor: When running +bare-metal without the hypervisor, the additional groups appear to behave +just like all others. The boot firmware uses some of the additional groups, +so ignoring them in this situation leads to stream match conflicts whenever +we allocate a new SMR group for the same SID. + +The workaround exists primarily because the bypass quirk detection fails +when using a S2CR register from the additional matching groups, so let's +perform the test with the last reliable S2CR (127) and then limit the +number of SMR groups only if we detect that we are running below the +hypervisor (because of the bypass quirk). + +Fixes: 122611347326 ("iommu/arm-smmu-qcom: Limit the SMR groups to 128") +Signed-off-by: Stephan Gerhold +Signed-off-by: Will Deacon +Signed-off-by: Sasha Levin +--- + drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 27 ++++++++++++++-------- + 1 file changed, 17 insertions(+), 10 deletions(-) + +diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +index 3d03136697963..62e2ab488c1be 100644 +--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c ++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c +@@ -295,17 +295,19 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + /* + * Some platforms support more than the Arm SMMU architected maximum of +- * 128 stream matching groups. For unknown reasons, the additional +- * groups don't exhibit the same behavior as the architected registers, +- * so limit the groups to 128 until the behavior is fixed for the other +- * groups. ++ * 128 stream matching groups. The additional registers appear to have ++ * the same behavior as the architected registers in the hardware. ++ * However, on some firmware versions, the hypervisor does not ++ * correctly trap and emulate accesses to the additional registers, ++ * resulting in unexpected behavior. ++ * ++ * If there are more than 128 groups, use the last reliable group to ++ * detect if we need to apply the bypass quirk. + */ +- if (smmu->num_mapping_groups > 128) { +- dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); +- smmu->num_mapping_groups = 128; +- } +- +- last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); ++ if (smmu->num_mapping_groups > 128) ++ last_s2cr = ARM_SMMU_GR0_S2CR(127); ++ else ++ last_s2cr = ARM_SMMU_GR0_S2CR(smmu->num_mapping_groups - 1); + + /* + * With some firmware versions writes to S2CR of type FAULT are +@@ -328,6 +330,11 @@ static int qcom_smmu_cfg_probe(struct arm_smmu_device *smmu) + + reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, CBAR_TYPE_S1_TRANS_S2_BYPASS); + arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(qsmmu->bypass_cbndx), reg); ++ ++ if (smmu->num_mapping_groups > 128) { ++ dev_notice(smmu->dev, "\tLimiting the stream matching groups to 128\n"); ++ smmu->num_mapping_groups = 128; ++ } + } + + for (i = 0; i < smmu->num_mapping_groups; i++) { +-- +2.51.0 + diff --git a/queue-6.6/ipv6-clear-ra-flags-when-adding-a-static-route.patch b/queue-6.6/ipv6-clear-ra-flags-when-adding-a-static-route.patch new file mode 100644 index 0000000000..5e3f4056cf --- /dev/null +++ b/queue-6.6/ipv6-clear-ra-flags-when-adding-a-static-route.patch @@ -0,0 +1,54 @@ +From b5a1bb8026af2387ce68275023f7c3771f1ff81e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 15 Nov 2025 10:59:38 +0100 +Subject: ipv6: clear RA flags when adding a static route + +From: Fernando Fernandez Mancera + +[ Upstream commit f72514b3c5698e4b900b25345e09f9ed33123de6 ] + +When an IPv6 Router Advertisement (RA) is received for a prefix, the +kernel creates the corresponding on-link route with flags RTF_ADDRCONF +and RTF_PREFIX_RT configured and RTF_EXPIRES if lifetime is set. + +If later a user configures a static IPv6 address on the same prefix the +kernel clears the RTF_EXPIRES flag but it doesn't clear the RTF_ADDRCONF +and RTF_PREFIX_RT. When the next RA for that prefix is received, the +kernel sees the route as RA-learned and wrongly configures back the +lifetime. This is problematic because if the route expires, the static +address won't have the corresponding on-link route. + +This fix clears the RTF_ADDRCONF and RTF_PREFIX_RT flags preventing that +the lifetime is configured when the next RA arrives. If the static +address is deleted, the route becomes RA-learned again. + +Fixes: 14ef37b6d00e ("ipv6: fix route lookup in addrconf_prefix_rcv()") +Reported-by: Garri Djavadyan +Closes: https://lore.kernel.org/netdev/ba807d39aca5b4dcf395cc11dca61a130a52cfd3.camel@gmail.com/ +Signed-off-by: Fernando Fernandez Mancera +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20251115095939.6967-1-fmancera@suse.de +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ip6_fib.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index ab84e2dd682f8..646ff1276aff2 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -1136,6 +1136,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + fib6_set_expires(iter, rt->expires); + fib6_add_gc_list(iter); + } ++ if (!(rt->fib6_flags & (RTF_ADDRCONF | RTF_PREFIX_RT))) { ++ iter->fib6_flags &= ~RTF_ADDRCONF; ++ iter->fib6_flags &= ~RTF_PREFIX_RT; ++ } + + if (rt->fib6_pmtu) + fib6_metric_set(iter, RTAX_MTU, +-- +2.51.0 + diff --git a/queue-6.6/irqchip-imx-mu-msi-fix-section-mismatch.patch b/queue-6.6/irqchip-imx-mu-msi-fix-section-mismatch.patch new file mode 100644 index 0000000000..1149df98a8 --- /dev/null +++ b/queue-6.6/irqchip-imx-mu-msi-fix-section-mismatch.patch @@ -0,0 +1,63 @@ +From 8db7751aabe6b8a1f65116023d9a9ae1db5e468a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:06 +0200 +Subject: irqchip/imx-mu-msi: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 64acfd8e680ff8992c101fe19aadb112ce551072 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 70afdab904d2 ("irqchip: Add IMX MU MSI controller driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-imx-mu-msi.c | 14 +++++--------- + 1 file changed, 5 insertions(+), 9 deletions(-) + +diff --git a/drivers/irqchip/irq-imx-mu-msi.c b/drivers/irqchip/irq-imx-mu-msi.c +index 90d41c1407acf..49e9742b1c55d 100644 +--- a/drivers/irqchip/irq-imx-mu-msi.c ++++ b/drivers/irqchip/irq-imx-mu-msi.c +@@ -303,9 +303,8 @@ static const struct imx_mu_dcfg imx_mu_cfg_imx8ulp = { + }, + }; + +-static int __init imx_mu_of_init(struct device_node *dn, +- struct device_node *parent, +- const struct imx_mu_dcfg *cfg) ++static int imx_mu_of_init(struct device_node *dn, struct device_node *parent, ++ const struct imx_mu_dcfg *cfg) + { + struct platform_device *pdev = of_find_device_by_node(dn); + struct device_link *pd_link_a; +@@ -423,20 +422,17 @@ static const struct dev_pm_ops imx_mu_pm_ops = { + imx_mu_runtime_resume, NULL) + }; + +-static int __init imx_mu_imx7ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx7ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx7ulp); + } + +-static int __init imx_mu_imx6sx_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx6sx_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx6sx); + } + +-static int __init imx_mu_imx8ulp_of_init(struct device_node *dn, +- struct device_node *parent) ++static int imx_mu_imx8ulp_of_init(struct device_node *dn, struct device_node *parent) + { + return imx_mu_of_init(dn, parent, &imx_mu_cfg_imx8ulp); + } +-- +2.51.0 + diff --git a/queue-6.6/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch b/queue-6.6/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch new file mode 100644 index 0000000000..ac75648bdf --- /dev/null +++ b/queue-6.6/irqchip-irq-bcm7038-l1-fix-section-mismatch.patch @@ -0,0 +1,50 @@ +From f017a19f6a03a002e715b4b6b4d3306333673400 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:03 +0200 +Subject: irqchip/irq-bcm7038-l1: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit e9db5332caaf4789ae3bafe72f61ad8e6e0c2d81 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callback must not live in init. + +Fixes: c057c799e379 ("irqchip/irq-bcm7038-l1: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7038-l1.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7038-l1.c b/drivers/irqchip/irq-bcm7038-l1.c +index 24ca1d656adc5..51d38a92ec200 100644 +--- a/drivers/irqchip/irq-bcm7038-l1.c ++++ b/drivers/irqchip/irq-bcm7038-l1.c +@@ -219,9 +219,8 @@ static int bcm7038_l1_set_affinity(struct irq_data *d, + } + #endif + +-static int __init bcm7038_l1_init_one(struct device_node *dn, +- unsigned int idx, +- struct bcm7038_l1_chip *intc) ++static int bcm7038_l1_init_one(struct device_node *dn, unsigned int idx, ++ struct bcm7038_l1_chip *intc) + { + struct resource res; + resource_size_t sz; +@@ -395,8 +394,7 @@ static const struct irq_domain_ops bcm7038_l1_domain_ops = { + .map = bcm7038_l1_map, + }; + +-static int __init bcm7038_l1_of_init(struct device_node *dn, +- struct device_node *parent) ++static int bcm7038_l1_of_init(struct device_node *dn, struct device_node *parent) + { + struct bcm7038_l1_chip *intc; + int idx, ret; +-- +2.51.0 + diff --git a/queue-6.6/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch b/queue-6.6/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..feb1611cbd --- /dev/null +++ b/queue-6.6/irqchip-irq-bcm7120-l2-fix-section-mismatch.patch @@ -0,0 +1,79 @@ +From 1b5774c108087f52fa35472f1a72e4f7cf53dc8f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:04 +0200 +Subject: irqchip/irq-bcm7120-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bfc0c5beab1fde843677923cf008f41d583c980a ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 3ac268d5ed22 ("irqchip/irq-bcm7120-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-bcm7120-l2.c | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/drivers/irqchip/irq-bcm7120-l2.c b/drivers/irqchip/irq-bcm7120-l2.c +index 1e9dab6e0d86f..bb6e56629e532 100644 +--- a/drivers/irqchip/irq-bcm7120-l2.c ++++ b/drivers/irqchip/irq-bcm7120-l2.c +@@ -147,8 +147,7 @@ static int bcm7120_l2_intc_init_one(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_7120(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + int ret; + +@@ -181,8 +180,7 @@ static int __init bcm7120_l2_intc_iomap_7120(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, +- struct bcm7120_l2_intc_data *data) ++static int bcm7120_l2_intc_iomap_3380(struct device_node *dn, struct bcm7120_l2_intc_data *data) + { + unsigned int gc_idx; + +@@ -212,10 +210,9 @@ static int __init bcm7120_l2_intc_iomap_3380(struct device_node *dn, + return 0; + } + +-static int __init bcm7120_l2_intc_probe(struct device_node *dn, +- struct device_node *parent, ++static int bcm7120_l2_intc_probe(struct device_node *dn, struct device_node *parent, + int (*iomap_regs_fn)(struct device_node *, +- struct bcm7120_l2_intc_data *), ++ struct bcm7120_l2_intc_data *), + const char *intc_name) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; +@@ -343,15 +340,13 @@ static int __init bcm7120_l2_intc_probe(struct device_node *dn, + return ret; + } + +-static int __init bcm7120_l2_intc_probe_7120(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_7120(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_7120, + "BCM7120 L2"); + } + +-static int __init bcm7120_l2_intc_probe_3380(struct device_node *dn, +- struct device_node *parent) ++static int bcm7120_l2_intc_probe_3380(struct device_node *dn, struct device_node *parent) + { + return bcm7120_l2_intc_probe(dn, parent, bcm7120_l2_intc_iomap_3380, + "BCM3380 L2"); +-- +2.51.0 + diff --git a/queue-6.6/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch b/queue-6.6/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch new file mode 100644 index 0000000000..06c4633695 --- /dev/null +++ b/queue-6.6/irqchip-irq-brcmstb-l2-fix-section-mismatch.patch @@ -0,0 +1,58 @@ +From 27215d5481379d597a87f72c5e993db9f8b7762a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:05 +0200 +Subject: irqchip/irq-brcmstb-l2: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit bbe1775924478e95372c2f896064ab6446000713 ] + +Platform drivers can be probed after their init sections have been +discarded so the irqchip init callbacks must not live in init. + +Fixes: 51d9db5c8fbb ("irqchip/irq-brcmstb-l2: Switch to IRQCHIP_PLATFORM_DRIVER") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Reviewed-by: Florian Fainelli +Signed-off-by: Sasha Levin +--- + drivers/irqchip/irq-brcmstb-l2.c | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/drivers/irqchip/irq-brcmstb-l2.c b/drivers/irqchip/irq-brcmstb-l2.c +index 2b0b3175cea06..23a4708684591 100644 +--- a/drivers/irqchip/irq-brcmstb-l2.c ++++ b/drivers/irqchip/irq-brcmstb-l2.c +@@ -157,10 +157,8 @@ static void brcmstb_l2_intc_resume(struct irq_data *d) + irq_gc_unlock_irqrestore(gc, flags); + } + +-static int __init brcmstb_l2_intc_of_init(struct device_node *np, +- struct device_node *parent, +- const struct brcmstb_intc_init_params +- *init_params) ++static int brcmstb_l2_intc_of_init(struct device_node *np, struct device_node *parent, ++ const struct brcmstb_intc_init_params *init_params) + { + unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; + unsigned int set = 0; +@@ -276,14 +274,12 @@ static int __init brcmstb_l2_intc_of_init(struct device_node *np, + return ret; + } + +-static int __init brcmstb_l2_edge_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_edge_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_edge_intc_init); + } + +-static int __init brcmstb_l2_lvl_intc_of_init(struct device_node *np, +- struct device_node *parent) ++static int brcmstb_l2_lvl_intc_of_init(struct device_node *np, struct device_node *parent) + { + return brcmstb_l2_intc_of_init(np, parent, &l2_lvl_intc_init); + } +-- +2.51.0 + diff --git a/queue-6.6/irqchip-qcom-irq-combiner-fix-section-mismatch.patch b/queue-6.6/irqchip-qcom-irq-combiner-fix-section-mismatch.patch new file mode 100644 index 0000000000..810faf6804 --- /dev/null +++ b/queue-6.6/irqchip-qcom-irq-combiner-fix-section-mismatch.patch @@ -0,0 +1,36 @@ +From 9c77259a75150b64d73b63a093f9d58876ad7fc0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 13 Oct 2025 11:46:09 +0200 +Subject: irqchip/qcom-irq-combiner: Fix section mismatch + +From: Johan Hovold + +[ Upstream commit 9b685058ca936752285c5520d351b828312ac965 ] + +Platform drivers can be probed after their init sections have been +discarded so the probe callback must not live in init. + +Fixes: f20cc9b00c7b ("irqchip/qcom: Add IRQ combiner driver") +Signed-off-by: Johan Hovold +Signed-off-by: Thomas Gleixner +Signed-off-by: Sasha Levin +--- + drivers/irqchip/qcom-irq-combiner.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/irqchip/qcom-irq-combiner.c b/drivers/irqchip/qcom-irq-combiner.c +index 18e696dc7f4d6..9308088773be7 100644 +--- a/drivers/irqchip/qcom-irq-combiner.c ++++ b/drivers/irqchip/qcom-irq-combiner.c +@@ -222,7 +222,7 @@ static int get_registers(struct platform_device *pdev, struct combiner *comb) + return 0; + } + +-static int __init combiner_probe(struct platform_device *pdev) ++static int combiner_probe(struct platform_device *pdev) + { + struct combiner *combiner; + int nregs; +-- +2.51.0 + diff --git a/queue-6.6/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch b/queue-6.6/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch new file mode 100644 index 0000000000..8437bea92b --- /dev/null +++ b/queue-6.6/kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch @@ -0,0 +1,51 @@ +From e67cd8ba535060cc62b94e9a2d5f7f067e9a57af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 08:13:32 -0700 +Subject: kernfs: fix memory leak of kernfs_iattrs in __kernfs_new_node + +From: Will Rosenberg + +[ Upstream commit 382b1e8f30f779af8d6d33268e53df7de579ef3c ] + +There exists a memory leak of kernfs_iattrs contained as an element +of kernfs_node allocated in __kernfs_new_node(). __kernfs_setattr() +allocates kernfs_iattrs as a sub-object, and the LSM security check +incorrectly errors out and does not free the kernfs_iattrs sub-object. + +Make an additional error out case that properly frees kernfs_iattrs if +security_kernfs_init_security() fails. + +Fixes: e19dfdc83b60 ("kernfs: initialize security of newly created nodes") +Co-developed-by: Oliver Rosenberg +Signed-off-by: Oliver Rosenberg +Signed-off-by: Will Rosenberg +Link: https://patch.msgid.link/20251125151332.2010687-1-whrosenb@asu.edu +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + fs/kernfs/dir.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c +index f6e2a4523f7e6..cbbf28334db4e 100644 +--- a/fs/kernfs/dir.c ++++ b/fs/kernfs/dir.c +@@ -662,11 +662,14 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, + if (parent) { + ret = security_kernfs_init_security(parent, kn); + if (ret) +- goto err_out3; ++ goto err_out4; + } + + return kn; + ++ err_out4: ++ simple_xattrs_free(&kn->iattr->xattrs, NULL); ++ kmem_cache_free(kernfs_iattrs_cache, kn->iattr); + err_out3: + spin_lock(&kernfs_idr_lock); + idr_remove(&root->ino_idr, (u32)kernfs_ino(kn)); +-- +2.51.0 + diff --git a/queue-6.6/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch b/queue-6.6/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch new file mode 100644 index 0000000000..08ad2e5e65 --- /dev/null +++ b/queue-6.6/leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch @@ -0,0 +1,113 @@ +From e1f25843b570e2dbe40612dd0add7fb21a266cc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Oct 2025 10:16:20 +0800 +Subject: leds: netxbig: Fix GPIO descriptor leak in error paths + +From: Haotian Zhang + +[ Upstream commit 03865dd8af52eb16c38062df2ed30a91b604780e ] + +The function netxbig_gpio_ext_get() acquires GPIO descriptors but +fails to release them when errors occur mid-way through initialization. +The cleanup callback registered by devm_add_action_or_reset() only +runs on success, leaving acquired GPIOs leaked on error paths. + +Add goto-based error handling to release all acquired GPIOs before +returning errors. + +Fixes: 9af512e81964 ("leds: netxbig: Convert to use GPIO descriptors") +Suggested-by: Markus Elfring +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251031021620.781-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/leds/leds-netxbig.c | 36 ++++++++++++++++++++++++++---------- + 1 file changed, 26 insertions(+), 10 deletions(-) + +diff --git a/drivers/leds/leds-netxbig.c b/drivers/leds/leds-netxbig.c +index 6692de0af68f1..ea0801b9cb010 100644 +--- a/drivers/leds/leds-netxbig.c ++++ b/drivers/leds/leds-netxbig.c +@@ -364,6 +364,9 @@ static int netxbig_gpio_ext_get(struct device *dev, + if (!addr) + return -ENOMEM; + ++ gpio_ext->addr = addr; ++ gpio_ext->num_addr = 0; ++ + /* + * We cannot use devm_ managed resources with these GPIO descriptors + * since they are associated with the "GPIO extension device" which +@@ -375,45 +378,58 @@ static int netxbig_gpio_ext_get(struct device *dev, + gpiod = gpiod_get_index(gpio_ext_dev, "addr", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_set_code; + gpiod_set_consumer_name(gpiod, "GPIO extension addr"); + addr[i] = gpiod; ++ gpio_ext->num_addr++; + } +- gpio_ext->addr = addr; +- gpio_ext->num_addr = num_addr; + + ret = gpiod_count(gpio_ext_dev, "data"); + if (ret < 0) { + dev_err(dev, + "Failed to count GPIOs in DT property data-gpios\n"); +- return ret; ++ goto err_free_addr; + } + num_data = ret; + data = devm_kcalloc(dev, num_data, sizeof(*data), GFP_KERNEL); +- if (!data) +- return -ENOMEM; ++ if (!data) { ++ ret = -ENOMEM; ++ goto err_free_addr; ++ } ++ ++ gpio_ext->data = data; ++ gpio_ext->num_data = 0; + + for (i = 0; i < num_data; i++) { + gpiod = gpiod_get_index(gpio_ext_dev, "data", i, + GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) +- return PTR_ERR(gpiod); ++ goto err_free_data; + gpiod_set_consumer_name(gpiod, "GPIO extension data"); + data[i] = gpiod; ++ gpio_ext->num_data++; + } +- gpio_ext->data = data; +- gpio_ext->num_data = num_data; + + gpiod = gpiod_get(gpio_ext_dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(gpiod)) { + dev_err(dev, + "Failed to get GPIO from DT property enable-gpio\n"); +- return PTR_ERR(gpiod); ++ goto err_free_data; + } + gpiod_set_consumer_name(gpiod, "GPIO extension enable"); + gpio_ext->enable = gpiod; + + return devm_add_action_or_reset(dev, netxbig_gpio_ext_remove, gpio_ext); ++ ++err_free_data: ++ for (i = 0; i < gpio_ext->num_data; i++) ++ gpiod_put(gpio_ext->data[i]); ++err_set_code: ++ ret = PTR_ERR(gpiod); ++err_free_addr: ++ for (i = 0; i < gpio_ext->num_addr; i++) ++ gpiod_put(gpio_ext->addr[i]); ++ return ret; + } + + static int netxbig_leds_get_of_pdata(struct device *dev, +-- +2.51.0 + diff --git a/queue-6.6/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch b/queue-6.6/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch new file mode 100644 index 0000000000..4613c4548f --- /dev/null +++ b/queue-6.6/lib-vsprintf-check-pointer-before-dereferencing-in-t.patch @@ -0,0 +1,51 @@ +From b8587dcb20a1efe7ec8bad263416b621b05025fd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 14:21:18 +0100 +Subject: lib/vsprintf: Check pointer before dereferencing in time_and_date() + +From: Andy Shevchenko + +[ Upstream commit 372a12bd5df0199aa234eaf8ef31ed7ecd61d40f ] + +The pointer may be invalid when gets to the printf(). In particular +the time_and_date() dereferencing it in some cases without checking. + +Move the check from rtc_str() to time_and_date() to cover all cases. + +Fixes: 7daac5b2fdf8 ("lib/vsprintf: Print time64_t in human readable format") +Signed-off-by: Andy Shevchenko +Reviewed-by: Petr Mladek +Link: https://patch.msgid.link/20251110132118.4113976-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Petr Mladek +Signed-off-by: Sasha Levin +--- + lib/vsprintf.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/lib/vsprintf.c b/lib/vsprintf.c +index f4ab2750cfc12..fc5ffc1b16903 100644 +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1859,9 +1859,6 @@ char *rtc_str(char *buf, char *end, const struct rtc_time *tm, + bool found = true; + int count = 2; + +- if (check_pointer(&buf, end, tm, spec)) +- return buf; +- + switch (fmt[count]) { + case 'd': + have_t = false; +@@ -1927,6 +1924,9 @@ static noinline_for_stack + char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec spec, + const char *fmt) + { ++ if (check_pointer(&buf, end, ptr, spec)) ++ return buf; ++ + switch (fmt[1]) { + case 'R': + return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); +-- +2.51.0 + diff --git a/queue-6.6/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch b/queue-6.6/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch new file mode 100644 index 0000000000..24880bb64a --- /dev/null +++ b/queue-6.6/macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch @@ -0,0 +1,100 @@ +From 7b8390491ed733cc114ee65675639fc957dc6f47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Aug 2025 17:10:35 +0800 +Subject: macintosh/mac_hid: fix race condition in mac_hid_toggle_emumouse + +From: Long Li + +[ Upstream commit 1e4b207ffe54cf33a4b7a2912c4110f89c73bf3f ] + +The following warning appears when running syzkaller, and this issue also +exists in the mainline code. + + ------------[ cut here ]------------ + list_add double add: new=ffffffffa57eee28, prev=ffffffffa57eee28, next=ffffffffa5e63100. + WARNING: CPU: 0 PID: 1491 at lib/list_debug.c:35 __list_add_valid_or_report+0xf7/0x130 + Modules linked in: + CPU: 0 PID: 1491 Comm: syz.1.28 Not tainted 6.6.0+ #3 + Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 + RIP: 0010:__list_add_valid_or_report+0xf7/0x130 + RSP: 0018:ff1100010dfb7b78 EFLAGS: 00010282 + RAX: 0000000000000000 RBX: ffffffffa57eee18 RCX: ffffffff97fc9817 + RDX: 0000000000040000 RSI: ffa0000002383000 RDI: 0000000000000001 + RBP: ffffffffa57eee28 R08: 0000000000000001 R09: ffe21c0021bf6f2c + R10: 0000000000000001 R11: 6464615f7473696c R12: ffffffffa5e63100 + R13: ffffffffa57eee28 R14: ffffffffa57eee28 R15: ff1100010dfb7d48 + FS: 00007fb14398b640(0000) GS:ff11000119600000(0000) knlGS:0000000000000000 + CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 + CR2: 0000000000000000 CR3: 000000010d096005 CR4: 0000000000773ef0 + DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 + DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 + PKRU: 80000000 + Call Trace: + + input_register_handler+0xb3/0x210 + mac_hid_start_emulation+0x1c5/0x290 + mac_hid_toggle_emumouse+0x20a/0x240 + proc_sys_call_handler+0x4c2/0x6e0 + new_sync_write+0x1b1/0x2d0 + vfs_write+0x709/0x950 + ksys_write+0x12a/0x250 + do_syscall_64+0x5a/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 + +The WARNING occurs when two processes concurrently write to the mac-hid +emulation sysctl, causing a race condition in mac_hid_toggle_emumouse(). +Both processes read old_val=0, then both try to register the input handler, +leading to a double list_add of the same handler. + + CPU0 CPU1 + ------------------------- ------------------------- + vfs_write() //write 1 vfs_write() //write 1 + proc_sys_write() proc_sys_write() + mac_hid_toggle_emumouse() mac_hid_toggle_emumouse() + old_val = *valp // old_val=0 + old_val = *valp // old_val=0 + mutex_lock_killable() + proc_dointvec() // *valp=1 + mac_hid_start_emulation() + input_register_handler() + mutex_unlock() + mutex_lock_killable() + proc_dointvec() + mac_hid_start_emulation() + input_register_handler() //Trigger Warning + mutex_unlock() + +Fix this by moving the old_val read inside the mutex lock region. + +Fixes: 99b089c3c38a ("Input: Mac button emulation - implement as an input filter") +Signed-off-by: Long Li +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/20250819091035.2263329-1-leo.lilong@huaweicloud.com +Signed-off-by: Sasha Levin +--- + drivers/macintosh/mac_hid.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c +index d8c4d5664145d..44e332ee99d38 100644 +--- a/drivers/macintosh/mac_hid.c ++++ b/drivers/macintosh/mac_hid.c +@@ -186,13 +186,14 @@ static int mac_hid_toggle_emumouse(struct ctl_table *table, int write, + void *buffer, size_t *lenp, loff_t *ppos) + { + int *valp = table->data; +- int old_val = *valp; ++ int old_val; + int rc; + + rc = mutex_lock_killable(&mac_hid_emumouse_mutex); + if (rc) + return rc; + ++ old_val = *valp; + rc = proc_dointvec(table, write, buffer, lenp, ppos); + + if (rc == 0 && write && *valp != old_val) { +-- +2.51.0 + diff --git a/queue-6.6/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch b/queue-6.6/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch new file mode 100644 index 0000000000..3f493478f2 --- /dev/null +++ b/queue-6.6/md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch @@ -0,0 +1,99 @@ +From ec5b5a82981eb3877cf0b75ed6fcab1ce414cebe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 16:55:57 +0800 +Subject: md/raid5: fix IO hang when array is broken with IO inflight + +From: Yu Kuai + +[ Upstream commit a913d1f6a7f607c110aeef8b58c8988f47a4b24e ] + +Following test can cause IO hang: + +mdadm -CvR /dev/md0 -l10 -n4 /dev/sd[abcd] --assume-clean --chunk=64K --bitmap=none +sleep 5 +echo 1 > /sys/block/sda/device/delete +echo 1 > /sys/block/sdb/device/delete +echo 1 > /sys/block/sdc/device/delete +echo 1 > /sys/block/sdd/device/delete + +dd if=/dev/md0 of=/dev/null bs=8k count=1 iflag=direct + +Root cause: + +1) all disks removed, however all rdevs in the array is still in sync, +IO will be issued normally. + +2) IO failure from sda, and set badblocks failed, sda will be faulty +and MD_SB_CHANGING_PENDING will be set. + +3) error recovery try to recover this IO from other disks, IO will be +issued to sdb, sdc, and sdd. + +4) IO failure from sdb, and set badblocks failed again, now array is +broken and will become read-only. + +5) IO failure from sdc and sdd, however, stripe can't be handled anymore +because MD_SB_CHANGING_PENDING is set: + +handle_stripe + handle_stripe + if (test_bit MD_SB_CHANGING_PENDING) + set_bit STRIPE_HANDLE + goto finish + // skip handling failed stripe + +release_stripe + if (test_bit STRIPE_HANDLE) + list_add_tail conf->hand_list + +6) later raid5d can't handle failed stripe as well: + +raid5d + md_check_recovery + md_update_sb + if (!md_is_rdwr()) + // can't clear pending bit + return + if (test_bit MD_SB_CHANGING_PENDING) + break; + // can't handle failed stripe + +Since MD_SB_CHANGING_PENDING can never be cleared for read-only array, +fix this problem by skip this checking for read-only array. + +Link: https://lore.kernel.org/linux-raid/20251117085557.770572-3-yukuai@fnnas.com +Fixes: d87f064f5874 ("md: never update metadata when array is read-only.") +Signed-off-by: Yu Kuai +Reviewed-by: Li Nan +Signed-off-by: Sasha Levin +--- + drivers/md/raid5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index f69e4a6a8a592..aad2b8c0c5418 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -5002,7 +5002,8 @@ static void handle_stripe(struct stripe_head *sh) + goto finish; + + if (s.handle_bad_blocks || +- test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags)) { ++ (md_is_rdwr(conf->mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &conf->mddev->sb_flags))) { + set_bit(STRIPE_HANDLE, &sh->state); + goto finish; + } +@@ -6829,7 +6830,8 @@ static void raid5d(struct md_thread *thread) + int batch_size, released; + unsigned int offset; + +- if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) ++ if (md_is_rdwr(mddev) && ++ test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) + break; + + released = release_stripe_list(conf, conf->temp_inactive_list); +-- +2.51.0 + diff --git a/queue-6.6/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch b/queue-6.6/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch new file mode 100644 index 0000000000..157f8f799c --- /dev/null +++ b/queue-6.6/mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch @@ -0,0 +1,41 @@ +From 29521016c0c65934d2a0814af870536ffb128212 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 10 Oct 2025 09:17:36 +0800 +Subject: mfd: da9055: Fix missing regmap_del_irq_chip() in error path + +From: Haotian Zhang + +[ Upstream commit 1b58acfd067ca16116b9234cd6b2d30cc8ab7502 ] + +When da9055_device_init() fails after regmap_add_irq_chip() +succeeds but mfd_add_devices() fails, the error handling path +only calls mfd_remove_devices() but forgets to call +regmap_del_irq_chip(). This results in a resource leak. + +Fix this by adding regmap_del_irq_chip() to the error path so +that resources are released properly. + +Fixes: 2896434cf272 ("mfd: DA9055 core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251010011737.1078-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/da9055-core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c +index 768302e05baa1..bdf6401d32d76 100644 +--- a/drivers/mfd/da9055-core.c ++++ b/drivers/mfd/da9055-core.c +@@ -388,6 +388,7 @@ int da9055_device_init(struct da9055 *da9055) + + err: + mfd_remove_devices(da9055->dev); ++ regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.6/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.6/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..d6d44bd9c3 --- /dev/null +++ b/queue-6.6/mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From 8f1063c653bab517e2d562c4c8097ae179db53af Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:14:27 +0800 +Subject: mfd: mt6358-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit 384bd58bf7095e4c4c8fcdbcede316ef342c630c ] + +If devm_request_threaded_irq() fails after irq_domain_add_linear() +succeeds in mt6358_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_add_linear() to properly release the IRQ domain. + +Fixes: 2b91c28f2abd ("mfd: Add support for the MediaTek MT6358 PMIC") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121427.583-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6358-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6358-irq.c b/drivers/mfd/mt6358-irq.c +index 49830b526ee88..10a0952615a17 100644 +--- a/drivers/mfd/mt6358-irq.c ++++ b/drivers/mfd/mt6358-irq.c +@@ -286,6 +286,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "Failed to register IRQ=%d, ret=%d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.6/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch b/queue-6.6/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch new file mode 100644 index 0000000000..0dbd632cec --- /dev/null +++ b/queue-6.6/mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch @@ -0,0 +1,40 @@ +From d56c0475e15476bb8baae0b99ed7d5def22356e8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 20:15:00 +0800 +Subject: mfd: mt6397-irq: Fix missing irq_domain_remove() in error path + +From: Haotian Zhang + +[ Upstream commit b4b1bd1f330fdd13706382be6c90ce9f58cee3f5 ] + +If devm_request_threaded_irq() fails after irq_domain_create_linear() +succeeds in mt6397_irq_init(), the function returns without removing +the created IRQ domain, leading to a resource leak. + +Call irq_domain_remove() in the error path after a successful +irq_domain_create_linear() to properly release the IRQ domain. + +Fixes: a4872e80ce7d ("mfd: mt6397: Extract IRQ related code from core driver") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251118121500.605-1-vulab@iscas.ac.cn +Signed-off-by: Lee Jones +Signed-off-by: Sasha Levin +--- + drivers/mfd/mt6397-irq.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/mfd/mt6397-irq.c b/drivers/mfd/mt6397-irq.c +index 886745b5b607c..1e83f7c7ce145 100644 +--- a/drivers/mfd/mt6397-irq.c ++++ b/drivers/mfd/mt6397-irq.c +@@ -208,6 +208,7 @@ int mt6397_irq_init(struct mt6397_chip *chip) + if (ret) { + dev_err(chip->dev, "failed to register irq=%d; err: %d\n", + chip->irq, ret); ++ irq_domain_remove(chip->irq_domain); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.6/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch b/queue-6.6/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch new file mode 100644 index 0000000000..5a6fa0453d --- /dev/null +++ b/queue-6.6/mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch @@ -0,0 +1,45 @@ +From 0b88d2e67a2a6b208b3d7cdac09b863702e2d9b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 06:24:15 +0000 +Subject: mt76: mt7615: Fix memory leak in mt7615_mcu_wtbl_sta_add() + +From: Zilin Guan + +[ Upstream commit 53d1548612670aa8b5d89745116cc33d9d172863 ] + +In mt7615_mcu_wtbl_sta_add(), an skb sskb is allocated. If the +subsequent call to mt76_connac_mcu_alloc_wtbl_req() fails, the function +returns an error without freeing sskb, leading to a memory leak. + +Fix this by calling dev_kfree_skb() on sskb in the error handling path +to ensure it is properly released. + +Fixes: 99c457d902cf9 ("mt76: mt7615: move mt7615_mcu_set_bmc to mt7615_mcu_ops") +Signed-off-by: Zilin Guan +Acked-by: Lorenzo Bianconi +Link: https://patch.msgid.link/20251113062415.103611-1-zilin@seu.edu.cn +Signed-off-by: Felix Fietkau +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/mediatek/mt76/mt7615/mcu.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +index e92040616a1f3..94adb22f8570f 100644 +--- a/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c ++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mcu.c +@@ -870,8 +870,10 @@ mt7615_mcu_wtbl_sta_add(struct mt7615_phy *phy, struct ieee80211_vif *vif, + wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(&dev->mt76, &msta->wcid, + WTBL_RESET_AND_SET, NULL, + &wskb); +- if (IS_ERR(wtbl_hdr)) ++ if (IS_ERR(wtbl_hdr)) { ++ dev_kfree_skb(sskb); + return PTR_ERR(wtbl_hdr); ++ } + + if (enable) { + mt76_connac_mcu_wtbl_generic_tlv(&dev->mt76, wskb, vif, sta, +-- +2.51.0 + diff --git a/queue-6.6/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch b/queue-6.6/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch new file mode 100644 index 0000000000..6bec577a78 --- /dev/null +++ b/queue-6.6/mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch @@ -0,0 +1,71 @@ +From b33fc2c2df6b04a860a8d494b90d17b8aea0d1e7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 14:54:46 +0300 +Subject: mtd: lpddr_cmds: fix signed shifts in lpddr_cmds + +From: Ivan Stepchenko + +[ Upstream commit c909fec69f84b39e63876c69b9df2c178c6b76ba ] + +There are several places where a value of type 'int' is shifted by +lpddr->chipshift. lpddr->chipshift is derived from QINFO geometry and +might reach 31 when QINFO reports a 2 GiB size - the maximum supported by +LPDDR(1) compliant chips. This may cause unexpected sign-extensions when +casting the integer value to the type of 'unsigned long'. + +Use '1UL << lpddr->chipshift' and cast 'j' to unsigned long before +shifting so the computation is performed at the destination width. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: c68264711ca6 ("[MTD] LPDDR Command set driver") +Signed-off-by: Ivan Stepchenko +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/lpddr/lpddr_cmds.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c +index 3c3939bc2dadc..2a2318230936e 100644 +--- a/drivers/mtd/lpddr/lpddr_cmds.c ++++ b/drivers/mtd/lpddr/lpddr_cmds.c +@@ -79,7 +79,7 @@ struct mtd_info *lpddr_cmdset(struct map_info *map) + mutex_init(&shared[i].lock); + for (j = 0; j < lpddr->qinfo->HWPartsNum; j++) { + *chip = lpddr->chips[i]; +- chip->start += j << lpddr->chipshift; ++ chip->start += (unsigned long)j << lpddr->chipshift; + chip->oldstate = chip->state = FL_READY; + chip->priv = &shared[i]; + /* those should be reset too since +@@ -559,7 +559,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + /* get the chip */ +@@ -575,7 +575,7 @@ static int lpddr_point(struct mtd_info *mtd, loff_t adr, size_t len, + len -= thislen; + + ofs = 0; +- last_end += 1 << lpddr->chipshift; ++ last_end += 1UL << lpddr->chipshift; + chipnum++; + chip = &lpddr->chips[chipnum]; + } +@@ -601,7 +601,7 @@ static int lpddr_unpoint (struct mtd_info *mtd, loff_t adr, size_t len) + break; + + if ((len + ofs - 1) >> lpddr->chipshift) +- thislen = (1<chipshift) - ofs; ++ thislen = (1UL << lpddr->chipshift) - ofs; + else + thislen = len; + +-- +2.51.0 + diff --git a/queue-6.6/mtd-nand-relax-ecc-parameter-validation-check.patch b/queue-6.6/mtd-nand-relax-ecc-parameter-validation-check.patch new file mode 100644 index 0000000000..4fccc6e8f0 --- /dev/null +++ b/queue-6.6/mtd-nand-relax-ecc-parameter-validation-check.patch @@ -0,0 +1,53 @@ +From a5c02ab00e1144c82deaf90ca24aec96abac6af2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:42 +1300 +Subject: mtd: nand: relax ECC parameter validation check + +From: Aryan Srivastava + +[ Upstream commit 050553c683f21eebd7d1020df9b2ec852e2a9e4e ] + +Due to the custom handling and layouts of certain nand controllers this +validity check will always fail for certain layouts. The check +inherently depends on even chunk sizing and this is not always the +case. + +Modify the check to only print a warning, instead of failing to +init the attached NAND. This allows various 8 bit and 12 ECC strength +layouts to be used. + +Fixes: 68c18dae6888 ("mtd: rawnand: marvell: add missing layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/nand_base.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c +index 7c3e3d70be8b0..fe0b298f8425e 100644 +--- a/drivers/mtd/nand/raw/nand_base.c ++++ b/drivers/mtd/nand/raw/nand_base.c +@@ -6450,11 +6450,14 @@ static int nand_scan_tail(struct nand_chip *chip) + ecc->steps = mtd->writesize / ecc->size; + if (!base->ecc.ctx.nsteps) + base->ecc.ctx.nsteps = ecc->steps; +- if (ecc->steps * ecc->size != mtd->writesize) { +- WARN(1, "Invalid ECC parameters\n"); +- ret = -EINVAL; +- goto err_nand_manuf_cleanup; +- } ++ ++ /* ++ * Validity check: Warn if ECC parameters are not compatible with page size. ++ * Due to the custom handling of ECC blocks in certain controllers the check ++ * may result in an expected failure. ++ */ ++ if (ecc->steps * ecc->size != mtd->writesize) ++ pr_warn("ECC parameters may be invalid in reference to underlying NAND chip\n"); + + if (!ecc->total) { + ecc->total = ecc->steps * ecc->bytes; +-- +2.51.0 + diff --git a/queue-6.6/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch b/queue-6.6/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch new file mode 100644 index 0000000000..019ceec104 --- /dev/null +++ b/queue-6.6/mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch @@ -0,0 +1,50 @@ +From 47cb32b86fc7132488bcc0c91aea440e180d4163 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 17:47:47 +0800 +Subject: mtd: rawnand: lpc32xx_slc: fix GPIO descriptor leak on probe error + and remove + +From: Haotian Zhang + +[ Upstream commit cdf44f1add4ec9ee80569d5a43e6e9bba0d74c7a ] + +The driver calls gpiod_get_optional() in the probe function but +never calls gpiod_put() in the remove function or in the probe +error path. This leads to a GPIO descriptor resource leak. +The lpc32xx_mlc.c driver in the same directory handles this +correctly by calling gpiod_put() on both paths. + +Add gpiod_put() in the remove function and in the probe error path +to fix the resource leak. + +Fixes: 6b923db2867c ("mtd: rawnand: lpc32xx_slc: switch to using gpiod API") +Signed-off-by: Haotian Zhang +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/lpc32xx_slc.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c +index 1c5fa855b9f2d..8abad092b0580 100644 +--- a/drivers/mtd/nand/raw/lpc32xx_slc.c ++++ b/drivers/mtd/nand/raw/lpc32xx_slc.c +@@ -933,6 +933,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) + dma_release_channel(host->dma_chan); + enable_wp: + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + + return res; + } +@@ -958,6 +959,7 @@ static void lpc32xx_nand_remove(struct platform_device *pdev) + writel(tmp, SLC_CTRL(host->io_base)); + + lpc32xx_wp_enable(host); ++ gpiod_put(host->wp_gpio); + } + + static int lpc32xx_nand_resume(struct platform_device *pdev) +-- +2.51.0 + diff --git a/queue-6.6/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch b/queue-6.6/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch new file mode 100644 index 0000000000..65a5e63672 --- /dev/null +++ b/queue-6.6/mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch @@ -0,0 +1,45 @@ +From 5a9f46d6ccf0280aa07836ce83021e10744ffcca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 00:35:51 +0800 +Subject: mtd: rawnand: renesas: Handle devm_pm_runtime_enable() errors + +From: Haotian Zhang + +[ Upstream commit a3623e1ae1ed6be4d49b2ccb9996a9d2b65c1828 ] + +devm_pm_runtime_enable() can fail due to memory allocation failures. +The current code ignores its return value and proceeds with +pm_runtime_resume_and_get(), which may operate on incorrectly +initialized runtime PM state. + +Check the return value of devm_pm_runtime_enable() and return the +error code if it fails. + +Fixes: 6a2277a0ebe7 ("mtd: rawnand: renesas: Use runtime PM instead of the raw clock API") +Signed-off-by: Haotian Zhang +Reviewed-by: Geert Uytterhoeven +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/renesas-nand-controller.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/mtd/nand/raw/renesas-nand-controller.c b/drivers/mtd/nand/raw/renesas-nand-controller.c +index a9e79f0acbe2a..46af7666b3c96 100644 +--- a/drivers/mtd/nand/raw/renesas-nand-controller.c ++++ b/drivers/mtd/nand/raw/renesas-nand-controller.c +@@ -1342,7 +1342,10 @@ static int rnandc_probe(struct platform_device *pdev) + if (IS_ERR(rnandc->regs)) + return PTR_ERR(rnandc->regs); + +- devm_pm_runtime_enable(&pdev->dev); ++ ret = devm_pm_runtime_enable(&pdev->dev); ++ if (ret) ++ return ret; ++ + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret < 0) + return ret; +-- +2.51.0 + diff --git a/queue-6.6/nbd-defer-config-put-in-recv_work.patch b/queue-6.6/nbd-defer-config-put-in-recv_work.patch new file mode 100644 index 0000000000..04d0392a68 --- /dev/null +++ b/queue-6.6/nbd-defer-config-put-in-recv_work.patch @@ -0,0 +1,102 @@ +From 66698762d975d836625a352e2d27a24ba636c073 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 15:02:02 +0800 +Subject: nbd: defer config put in recv_work + +From: Zheng Qixing + +[ Upstream commit 9517b82d8d422d426a988b213fdd45c6b417b86d ] + +There is one uaf issue in recv_work when running NBD_CLEAR_SOCK and +NBD_CMD_RECONFIGURE: + nbd_genl_connect // conf_ref=2 (connect and recv_work A) + nbd_open // conf_ref=3 + recv_work A done // conf_ref=2 + NBD_CLEAR_SOCK // conf_ref=1 + nbd_genl_reconfigure // conf_ref=2 (trigger recv_work B) + close nbd // conf_ref=1 + recv_work B + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Or only running NBD_CLEAR_SOCK: + nbd_genl_connect // conf_ref=2 + nbd_open // conf_ref=3 + NBD_CLEAR_SOCK // conf_ref=2 + close nbd + nbd_release + config_put // conf_ref=1 + recv_work + config_put // conf_ref=0 + atomic_dec(&config->recv_threads); -> UAF + +Commit 87aac3a80af5 ("nbd: call nbd_config_put() before notifying the +waiter") moved nbd_config_put() to run before waking up the waiter in +recv_work, in order to ensure that nbd_start_device_ioctl() would not +be woken up while nbd->task_recv was still uncleared. + +However, in nbd_start_device_ioctl(), after being woken up it explicitly +calls flush_workqueue() to make sure all current works are finished. +Therefore, there is no need to move the config put ahead of the wakeup. + +Move nbd_config_put() to the end of recv_work, so that the reference is +held for the whole lifetime of the worker thread. This makes sure the +config cannot be freed while recv_work is still running, even if clear ++ reconfigure interleave. + +In addition, we don't need to worry about recv_work dropping the last +nbd_put (which causes deadlock): + +path A (netlink with NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=1 (trigger recv_work) + open nbd // nbd_refs=2 + NBD_CLEAR_SOCK + close nbd + nbd_release + nbd_disconnect_and_put + flush_workqueue // recv_work done + nbd_config_put + nbd_put // nbd_refs=1 + nbd_put // nbd_refs=0 + queue_work + +path B (netlink without NBD_CFLAG_DESTROY_ON_DISCONNECT): + connect // nbd_refs=2 (trigger recv_work) + open nbd // nbd_refs=3 + NBD_CLEAR_SOCK // conf_refs=2 + close nbd + nbd_release + nbd_config_put // conf_refs=1 + nbd_put // nbd_refs=2 + recv_work done // conf_refs=0, nbd_refs=1 + rmmod // nbd_refs=0 + +Reported-by: syzbot+56fbf4c7ddf65e95c7cc@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/6907edce.a70a0220.37351b.0014.GAE@google.com/T/ +Fixes: 87aac3a80af5 ("nbd: make the config put is called before the notifying the waiter") +Depends-on: e2daec488c57 ("nbd: Fix hungtask when nbd_config_put") +Signed-off-by: Zheng Qixing +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 27a05b1521f69..9e190d220e98f 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -912,9 +912,9 @@ static void recv_work(struct work_struct *work) + nbd_mark_nsock_dead(nbd, nsock, 1); + mutex_unlock(&nsock->tx_lock); + +- nbd_config_put(nbd); + atomic_dec(&config->recv_threads); + wake_up(&config->recv_wq); ++ nbd_config_put(nbd); + kfree(args); + } + +-- +2.51.0 + diff --git a/queue-6.6/nbd-defer-config-unlock-in-nbd_genl_connect.patch b/queue-6.6/nbd-defer-config-unlock-in-nbd_genl_connect.patch new file mode 100644 index 0000000000..5171a816f5 --- /dev/null +++ b/queue-6.6/nbd-defer-config-unlock-in-nbd_genl_connect.patch @@ -0,0 +1,72 @@ +From ef11640cac5e92cd8409233102dd6c8ec0057a5c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 20:49:20 +0800 +Subject: nbd: defer config unlock in nbd_genl_connect + +From: Zheng Qixing + +[ Upstream commit 1649714b930f9ea6233ce0810ba885999da3b5d4 ] + +There is one use-after-free warning when running NBD_CMD_CONNECT and +NBD_CLEAR_SOCK: + +nbd_genl_connect + nbd_alloc_and_init_config // config_refs=1 + nbd_start_device // config_refs=2 + set NBD_RT_HAS_CONFIG_REF open nbd // config_refs=3 + recv_work done // config_refs=2 + NBD_CLEAR_SOCK // config_refs=1 + close nbd // config_refs=0 + refcount_inc -> uaf + +------------[ cut here ]------------ +refcount_t: addition on 0; use-after-free. +WARNING: CPU: 24 PID: 1014 at lib/refcount.c:25 refcount_warn_saturate+0x12e/0x290 + nbd_genl_connect+0x16d0/0x1ab0 + genl_family_rcv_msg_doit+0x1f3/0x310 + genl_rcv_msg+0x44a/0x790 + +The issue can be easily reproduced by adding a small delay before +refcount_inc(&nbd->config_refs) in nbd_genl_connect(): + + mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); ++ printk("before sleep\n"); ++ mdelay(5 * 1000); ++ printk("after sleep\n"); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } + +Fixes: e46c7287b1c2 ("nbd: add a basic netlink interface") +Signed-off-by: Zheng Qixing +Reviewed-by: Yu Kuai +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/nbd.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c +index 9e190d220e98f..8b7f306ec976f 100644 +--- a/drivers/block/nbd.c ++++ b/drivers/block/nbd.c +@@ -2147,12 +2147,13 @@ static int nbd_genl_connect(struct sk_buff *skb, struct genl_info *info) + + ret = nbd_start_device(nbd); + out: +- mutex_unlock(&nbd->config_lock); + if (!ret) { + set_bit(NBD_RT_HAS_CONFIG_REF, &config->runtime_flags); + refcount_inc(&nbd->config_refs); + nbd_connect_reply(info, nbd->index); + } ++ mutex_unlock(&nbd->config_lock); ++ + nbd_config_put(nbd); + if (put_dev) + nbd_put(nbd); +-- +2.51.0 + diff --git a/queue-6.6/net-ipv6-remove-expired-routes-with-a-separated-list.patch b/queue-6.6/net-ipv6-remove-expired-routes-with-a-separated-list.patch new file mode 100644 index 0000000000..b3e039f990 --- /dev/null +++ b/queue-6.6/net-ipv6-remove-expired-routes-with-a-separated-list.patch @@ -0,0 +1,412 @@ +From f5e334ec0d80bafac590e04f25ed582aca97c6d2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Feb 2024 14:06:51 -0800 +Subject: net/ipv6: Remove expired routes with a separated list of routes. + +From: Kui-Feng Lee + +[ Upstream commit 5eb902b8e7193cdcb33242af0a56502e6b5206e9 ] + +FIB6 GC walks trees of fib6_tables to remove expired routes. Walking a tree +can be expensive if the number of routes in a table is big, even if most of +them are permanent. Checking routes in a separated list of routes having +expiration will avoid this potential issue. + +Reviewed-by: David Ahern +Signed-off-by: Kui-Feng Lee +Signed-off-by: David S. Miller +Stable-dep-of: f72514b3c569 ("ipv6: clear RA flags when adding a static route") +Signed-off-by: Sasha Levin +--- + include/net/ip6_fib.h | 46 ++++++++++++++++++++++++++++++++- + net/ipv6/addrconf.c | 41 ++++++++++++++++++++++++----- + net/ipv6/ip6_fib.c | 60 +++++++++++++++++++++++++++++++++++++++---- + net/ipv6/ndisc.c | 10 +++++++- + net/ipv6/route.c | 13 ++++++++-- + 5 files changed, 154 insertions(+), 16 deletions(-) + +diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h +index 1121d614942c8..f4c5b705418c0 100644 +--- a/include/net/ip6_fib.h ++++ b/include/net/ip6_fib.h +@@ -179,6 +179,9 @@ struct fib6_info { + + refcount_t fib6_ref; + unsigned long expires; ++ ++ struct hlist_node gc_link; ++ + struct dst_metrics *fib6_metrics; + #define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1] + +@@ -249,12 +252,18 @@ static inline bool fib6_requires_src(const struct fib6_info *rt) + return rt->fib6_src.plen > 0; + } + ++/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever ++ * been added to a table before. ++ */ + static inline void fib6_clean_expires(struct fib6_info *f6i) + { + f6i->fib6_flags &= ~RTF_EXPIRES; + f6i->expires = 0; + } + ++/* The callers should hold f6i->fib6_table->tb6_lock if a route has ever ++ * been added to a table before. ++ */ + static inline void fib6_set_expires(struct fib6_info *f6i, + unsigned long expires) + { +@@ -335,8 +344,10 @@ static inline bool fib6_info_hold_safe(struct fib6_info *f6i) + + static inline void fib6_info_release(struct fib6_info *f6i) + { +- if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) ++ if (f6i && refcount_dec_and_test(&f6i->fib6_ref)) { ++ DEBUG_NET_WARN_ON_ONCE(!hlist_unhashed(&f6i->gc_link)); + call_rcu(&f6i->rcu, fib6_info_destroy_rcu); ++ } + } + + enum fib6_walk_state { +@@ -390,6 +401,7 @@ struct fib6_table { + struct inet_peer_base tb6_peers; + unsigned int flags; + unsigned int fib_seq; ++ struct hlist_head tb6_gc_hlist; /* GC candidates */ + #define RT6_TABLE_HAS_DFLT_ROUTER BIT(0) + }; + +@@ -506,6 +518,38 @@ void fib6_gc_cleanup(void); + + int fib6_init(void); + ++/* Add the route to the gc list if it is not already there ++ * ++ * The callers should hold f6i->fib6_table->tb6_lock. ++ */ ++static inline void fib6_add_gc_list(struct fib6_info *f6i) ++{ ++ /* If fib6_node is null, the f6i is not in (or removed from) the ++ * table. ++ * ++ * There is a gap between finding the f6i from the table and ++ * calling this function without the protection of the tb6_lock. ++ * This check makes sure the f6i is not added to the gc list when ++ * it is not on the table. ++ */ ++ if (!rcu_dereference_protected(f6i->fib6_node, ++ lockdep_is_held(&f6i->fib6_table->tb6_lock))) ++ return; ++ ++ if (hlist_unhashed(&f6i->gc_link)) ++ hlist_add_head(&f6i->gc_link, &f6i->fib6_table->tb6_gc_hlist); ++} ++ ++/* Remove the route from the gc list if it is on the list. ++ * ++ * The callers should hold f6i->fib6_table->tb6_lock. ++ */ ++static inline void fib6_remove_gc_list(struct fib6_info *f6i) ++{ ++ if (!hlist_unhashed(&f6i->gc_link)) ++ hlist_del_init(&f6i->gc_link); ++} ++ + struct ipv6_route_iter { + struct seq_net_private p; + struct fib6_walker w; +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 0e49ee83533b5..b606d77fe7fce 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1268,6 +1268,7 @@ static void + cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, + bool del_rt, bool del_peer) + { ++ struct fib6_table *table; + struct fib6_info *f6i; + + f6i = addrconf_get_prefix_route(del_peer ? &ifp->peer_addr : &ifp->addr, +@@ -1277,8 +1278,15 @@ cleanup_prefix_route(struct inet6_ifaddr *ifp, unsigned long expires, + if (del_rt) + ip6_del_rt(dev_net(ifp->idev->dev), f6i, false); + else { +- if (!(f6i->fib6_flags & RTF_EXPIRES)) ++ if (!(f6i->fib6_flags & RTF_EXPIRES)) { ++ table = f6i->fib6_table; ++ spin_lock_bh(&table->tb6_lock); ++ + fib6_set_expires(f6i, expires); ++ fib6_add_gc_list(f6i); ++ ++ spin_unlock_bh(&table->tb6_lock); ++ } + fib6_info_release(f6i); + } + } +@@ -2736,6 +2744,7 @@ EXPORT_SYMBOL_GPL(addrconf_prefix_rcv_add_addr); + void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) + { + struct prefix_info *pinfo; ++ struct fib6_table *table; + __u32 valid_lft; + __u32 prefered_lft; + int addr_type, err; +@@ -2812,11 +2821,20 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len, bool sllao) + if (valid_lft == 0) { + ip6_del_rt(net, rt, false); + rt = NULL; +- } else if (addrconf_finite_timeout(rt_expires)) { +- /* not infinity */ +- fib6_set_expires(rt, jiffies + rt_expires); + } else { +- fib6_clean_expires(rt); ++ table = rt->fib6_table; ++ spin_lock_bh(&table->tb6_lock); ++ ++ if (addrconf_finite_timeout(rt_expires)) { ++ /* not infinity */ ++ fib6_set_expires(rt, jiffies + rt_expires); ++ fib6_add_gc_list(rt); ++ } else { ++ fib6_clean_expires(rt); ++ fib6_remove_gc_list(rt); ++ } ++ ++ spin_unlock_bh(&table->tb6_lock); + } + } else if (valid_lft) { + clock_t expires = 0; +@@ -4770,6 +4788,7 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, + unsigned long expires, u32 flags, + bool modify_peer) + { ++ struct fib6_table *table; + struct fib6_info *f6i; + u32 prio; + +@@ -4790,10 +4809,18 @@ static int modify_prefix_route(struct inet6_ifaddr *ifp, + ifp->rt_priority, ifp->idev->dev, + expires, flags, GFP_KERNEL); + } else { +- if (!expires) ++ table = f6i->fib6_table; ++ spin_lock_bh(&table->tb6_lock); ++ ++ if (!expires) { + fib6_clean_expires(f6i); +- else ++ fib6_remove_gc_list(f6i); ++ } else { + fib6_set_expires(f6i, expires); ++ fib6_add_gc_list(f6i); ++ } ++ ++ spin_unlock_bh(&table->tb6_lock); + + fib6_info_release(f6i); + } +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index c44136cbbaa1f..ab84e2dd682f8 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -160,6 +160,8 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh) + INIT_LIST_HEAD(&f6i->fib6_siblings); + refcount_set(&f6i->fib6_ref, 1); + ++ INIT_HLIST_NODE(&f6i->gc_link); ++ + return f6i; + } + +@@ -246,6 +248,7 @@ static struct fib6_table *fib6_alloc_table(struct net *net, u32 id) + net->ipv6.fib6_null_entry); + table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&table->tb6_peers); ++ INIT_HLIST_HEAD(&table->tb6_gc_hlist); + } + + return table; +@@ -1063,6 +1066,9 @@ static void fib6_purge_rt(struct fib6_info *rt, struct fib6_node *fn, + lockdep_is_held(&table->tb6_lock)); + } + } ++ ++ fib6_clean_expires(rt); ++ fib6_remove_gc_list(rt); + } + + /* +@@ -1123,10 +1129,13 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct fib6_info *rt, + WRITE_ONCE(rt->fib6_nsiblings, 0); + if (!(iter->fib6_flags & RTF_EXPIRES)) + return -EEXIST; +- if (!(rt->fib6_flags & RTF_EXPIRES)) ++ if (!(rt->fib6_flags & RTF_EXPIRES)) { + fib6_clean_expires(iter); +- else ++ fib6_remove_gc_list(iter); ++ } else { + fib6_set_expires(iter, rt->expires); ++ fib6_add_gc_list(iter); ++ } + + if (rt->fib6_pmtu) + fib6_metric_set(iter, RTAX_MTU, +@@ -1491,6 +1500,10 @@ int fib6_add(struct fib6_node *root, struct fib6_info *rt, + if (rt->nh) + list_add(&rt->nh_list, &rt->nh->f6i_list); + __fib6_update_sernum_upto_root(rt, fib6_new_sernum(info->nl_net)); ++ ++ if (rt->fib6_flags & RTF_EXPIRES) ++ fib6_add_gc_list(rt); ++ + fib6_start_gc(info->nl_net, rt); + } + +@@ -2294,9 +2307,8 @@ static void fib6_flush_trees(struct net *net) + * Garbage collection + */ + +-static int fib6_age(struct fib6_info *rt, void *arg) ++static int fib6_age(struct fib6_info *rt, struct fib6_gc_args *gc_args) + { +- struct fib6_gc_args *gc_args = arg; + unsigned long now = jiffies; + + /* +@@ -2321,6 +2333,42 @@ static int fib6_age(struct fib6_info *rt, void *arg) + return 0; + } + ++static void fib6_gc_table(struct net *net, ++ struct fib6_table *tb6, ++ struct fib6_gc_args *gc_args) ++{ ++ struct fib6_info *rt; ++ struct hlist_node *n; ++ struct nl_info info = { ++ .nl_net = net, ++ .skip_notify = false, ++ }; ++ ++ hlist_for_each_entry_safe(rt, n, &tb6->tb6_gc_hlist, gc_link) ++ if (fib6_age(rt, gc_args) == -1) ++ fib6_del(rt, &info); ++} ++ ++static void fib6_gc_all(struct net *net, struct fib6_gc_args *gc_args) ++{ ++ struct fib6_table *table; ++ struct hlist_head *head; ++ unsigned int h; ++ ++ rcu_read_lock(); ++ for (h = 0; h < FIB6_TABLE_HASHSZ; h++) { ++ head = &net->ipv6.fib_table_hash[h]; ++ hlist_for_each_entry_rcu(table, head, tb6_hlist) { ++ spin_lock_bh(&table->tb6_lock); ++ ++ fib6_gc_table(net, table, gc_args); ++ ++ spin_unlock_bh(&table->tb6_lock); ++ } ++ } ++ rcu_read_unlock(); ++} ++ + void fib6_run_gc(unsigned long expires, struct net *net, bool force) + { + struct fib6_gc_args gc_args; +@@ -2336,7 +2384,7 @@ void fib6_run_gc(unsigned long expires, struct net *net, bool force) + net->ipv6.sysctl.ip6_rt_gc_interval; + gc_args.more = 0; + +- fib6_clean_all(net, fib6_age, &gc_args); ++ fib6_gc_all(net, &gc_args); + now = jiffies; + net->ipv6.ip6_rt_last_gc = now; + +@@ -2396,6 +2444,7 @@ static int __net_init fib6_net_init(struct net *net) + net->ipv6.fib6_main_tbl->tb6_root.fn_flags = + RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&net->ipv6.fib6_main_tbl->tb6_peers); ++ INIT_HLIST_HEAD(&net->ipv6.fib6_main_tbl->tb6_gc_hlist); + + #ifdef CONFIG_IPV6_MULTIPLE_TABLES + net->ipv6.fib6_local_tbl = kzalloc(sizeof(*net->ipv6.fib6_local_tbl), +@@ -2408,6 +2457,7 @@ static int __net_init fib6_net_init(struct net *net) + net->ipv6.fib6_local_tbl->tb6_root.fn_flags = + RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; + inet_peer_base_init(&net->ipv6.fib6_local_tbl->tb6_peers); ++ INIT_HLIST_HEAD(&net->ipv6.fib6_local_tbl->tb6_gc_hlist); + #endif + fib6_tables_init(net); + +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 8d853971f2f68..d8e5e2833eded 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -1241,6 +1241,7 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) + struct ndisc_options ndopts; + struct fib6_info *rt = NULL; + struct inet6_dev *in6_dev; ++ struct fib6_table *table; + u32 defrtr_usr_metric; + unsigned int pref = 0; + __u32 old_if_flags; +@@ -1413,8 +1414,15 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb) + inet6_rt_notify(RTM_NEWROUTE, rt, &nlinfo, NLM_F_REPLACE); + } + +- if (rt) ++ if (rt) { ++ table = rt->fib6_table; ++ spin_lock_bh(&table->tb6_lock); ++ + fib6_set_expires(rt, jiffies + (HZ * lifetime)); ++ fib6_add_gc_list(rt); ++ ++ spin_unlock_bh(&table->tb6_lock); ++ } + if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && + ra_msg->icmph.icmp6_hop_limit) { + if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) { +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index eb9e505f71f97..929f92b555113 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -971,6 +971,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, + struct net *net = dev_net(dev); + struct route_info *rinfo = (struct route_info *) opt; + struct in6_addr prefix_buf, *prefix; ++ struct fib6_table *table; + unsigned int pref; + unsigned long lifetime; + struct fib6_info *rt; +@@ -1029,10 +1030,18 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len, + (rt->fib6_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); + + if (rt) { +- if (!addrconf_finite_timeout(lifetime)) ++ table = rt->fib6_table; ++ spin_lock_bh(&table->tb6_lock); ++ ++ if (!addrconf_finite_timeout(lifetime)) { + fib6_clean_expires(rt); +- else ++ fib6_remove_gc_list(rt); ++ } else { + fib6_set_expires(rt, jiffies + HZ * lifetime); ++ fib6_add_gc_list(rt); ++ } ++ ++ spin_unlock_bh(&table->tb6_lock); + + fib6_info_release(rt); + } +-- +2.51.0 + diff --git a/queue-6.6/net-phy-adin1100-fix-software-power-down-ready-condi.patch b/queue-6.6/net-phy-adin1100-fix-software-power-down-ready-condi.patch new file mode 100644 index 0000000000..f075e3196d --- /dev/null +++ b/queue-6.6/net-phy-adin1100-fix-software-power-down-ready-condi.patch @@ -0,0 +1,54 @@ +From 64d410c0107669da01ec79cb6a2661ca1dbf6e96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 13:47:36 +0100 +Subject: net: phy: adin1100: Fix software power-down ready condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Alexander Dahl + +[ Upstream commit bccaf1fe08f2c9f96f6bc38391d41e67f6bf38e3 ] + +Value CRSM_SFT_PD written to Software Power-Down Control Register +(CRSM_SFT_PD_CNTRL) is 0x01 and therefor different to value +CRSM_SFT_PD_RDY (0x02) read from System Status Register (CRSM_STAT) for +confirmation powerdown has been reached. + +The condition could have only worked when disabling powerdown +(both 0x00), but never when enabling it (0x01 != 0x02). + +Result is a timeout, like so: + + $ ifdown eth0 + macb f802c000.ethernet eth0: Link is Down + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + ADIN1100 f802c000.ethernet-ffffffff:01: adin_set_powerdown_mode failed: -110 + +Fixes: 7eaf9132996a ("net: phy: adin1100: Add initial support for ADIN1100 industrial PHY") +Signed-off-by: Alexander Dahl +Reviewed-by: Russell King (Oracle) +Acked-by: Nuno Sá +Link: https://patch.msgid.link/20251119124737.280939-2-ada@thorsis.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/adin1100.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/phy/adin1100.c b/drivers/net/phy/adin1100.c +index 7619d6185801c..2f47b7020e12b 100644 +--- a/drivers/net/phy/adin1100.c ++++ b/drivers/net/phy/adin1100.c +@@ -148,7 +148,7 @@ static int adin_set_powerdown_mode(struct phy_device *phydev, bool en) + return ret; + + return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, ADIN_CRSM_STAT, ret, +- (ret & ADIN_CRSM_SFT_PD_RDY) == val, ++ !!(ret & ADIN_CRSM_SFT_PD_RDY) == en, + 1000, 30000, true); + } + +-- +2.51.0 + diff --git a/queue-6.6/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch b/queue-6.6/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch new file mode 100644 index 0000000000..61c16c9be1 --- /dev/null +++ b/queue-6.6/net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch @@ -0,0 +1,158 @@ +From 5a5beeab349820fc3bc264da927580827e6fdec9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 17:14:14 -0700 +Subject: net/sched: sch_cake: Fix incorrect qlen reduction in cake_drop +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Xiang Mei + +[ Upstream commit 9fefc78f7f02d71810776fdeb119a05a946a27cc ] + +In cake_drop(), qdisc_tree_reduce_backlog() is used to update the qlen +and backlog of the qdisc hierarchy. Its caller, cake_enqueue(), assumes +that the parent qdisc will enqueue the current packet. However, this +assumption breaks when cake_enqueue() returns NET_XMIT_CN: the parent +qdisc stops enqueuing current packet, leaving the tree qlen/backlog +accounting inconsistent. This mismatch can lead to a NULL dereference +(e.g., when the parent Qdisc is qfq_qdisc). + +This patch computes the qlen/backlog delta in a more robust way by +observing the difference before and after the series of cake_drop() +calls, and then compensates the qdisc tree accounting if cake_enqueue() +returns NET_XMIT_CN. + +To ensure correct compensation when ACK thinning is enabled, a new +variable is introduced to keep qlen unchanged. + +Fixes: 15de71d06a40 ("net/sched: Make cake_enqueue return NET_XMIT_CN when past buffer_limit") +Signed-off-by: Xiang Mei +Reviewed-by: Toke Høiland-Jørgensen +Link: https://patch.msgid.link/20251128001415.377823-1-xmei5@asu.edu +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + net/sched/sch_cake.c | 58 ++++++++++++++++++++++++-------------------- + 1 file changed, 32 insertions(+), 26 deletions(-) + +diff --git a/net/sched/sch_cake.c b/net/sched/sch_cake.c +index 85984c91cf51f..14e06f474b6ca 100644 +--- a/net/sched/sch_cake.c ++++ b/net/sched/sch_cake.c +@@ -1609,7 +1609,6 @@ static unsigned int cake_drop(struct Qdisc *sch, struct sk_buff **to_free) + + __qdisc_drop(skb, to_free); + sch->q.qlen--; +- qdisc_tree_reduce_backlog(sch, 1, len); + + cake_heapify(q, 0); + +@@ -1755,14 +1754,14 @@ static void cake_reconfigure(struct Qdisc *sch); + static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + struct sk_buff **to_free) + { ++ u32 idx, tin, prev_qlen, prev_backlog, drop_id; + struct cake_sched_data *q = qdisc_priv(sch); +- int len = qdisc_pkt_len(skb); +- int ret; ++ int len = qdisc_pkt_len(skb), ret; + struct sk_buff *ack = NULL; + ktime_t now = ktime_get(); + struct cake_tin_data *b; + struct cake_flow *flow; +- u32 idx, tin; ++ bool same_flow = false; + + /* choose flow to insert into */ + idx = cake_classify(sch, &b, skb, q->flow_mode, &ret); +@@ -1835,6 +1834,8 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + consume_skb(skb); + } else { + /* not splitting */ ++ int ack_pkt_len = 0; ++ + cobalt_set_enqueue_time(skb, now); + get_cobalt_cb(skb)->adjusted_len = cake_overhead(q, skb); + flow_queue_add(flow, skb); +@@ -1845,13 +1846,13 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (ack) { + b->ack_drops++; + sch->qstats.drops++; +- b->bytes += qdisc_pkt_len(ack); +- len -= qdisc_pkt_len(ack); ++ ack_pkt_len = qdisc_pkt_len(ack); ++ b->bytes += ack_pkt_len; + q->buffer_used += skb->truesize - ack->truesize; + if (q->rate_flags & CAKE_FLAG_INGRESS) + cake_advance_shaper(q, b, ack, now, true); + +- qdisc_tree_reduce_backlog(sch, 1, qdisc_pkt_len(ack)); ++ qdisc_tree_reduce_backlog(sch, 1, ack_pkt_len); + consume_skb(ack); + } else { + sch->q.qlen++; +@@ -1860,11 +1861,11 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + + /* stats */ + b->packets++; +- b->bytes += len; +- b->backlogs[idx] += len; +- b->tin_backlog += len; +- sch->qstats.backlog += len; +- q->avg_window_bytes += len; ++ b->bytes += len - ack_pkt_len; ++ b->backlogs[idx] += len - ack_pkt_len; ++ b->tin_backlog += len - ack_pkt_len; ++ sch->qstats.backlog += len - ack_pkt_len; ++ q->avg_window_bytes += len - ack_pkt_len; + } + + if (q->overflow_timeout) +@@ -1939,24 +1940,29 @@ static s32 cake_enqueue(struct sk_buff *skb, struct Qdisc *sch, + if (q->buffer_used > q->buffer_max_used) + q->buffer_max_used = q->buffer_used; + +- if (q->buffer_used > q->buffer_limit) { +- bool same_flow = false; +- u32 dropped = 0; +- u32 drop_id; ++ if (q->buffer_used <= q->buffer_limit) ++ return NET_XMIT_SUCCESS; + +- while (q->buffer_used > q->buffer_limit) { +- dropped++; +- drop_id = cake_drop(sch, to_free); ++ prev_qlen = sch->q.qlen; ++ prev_backlog = sch->qstats.backlog; + +- if ((drop_id >> 16) == tin && +- (drop_id & 0xFFFF) == idx) +- same_flow = true; +- } +- b->drop_overlimit += dropped; ++ while (q->buffer_used > q->buffer_limit) { ++ drop_id = cake_drop(sch, to_free); ++ if ((drop_id >> 16) == tin && ++ (drop_id & 0xFFFF) == idx) ++ same_flow = true; ++ } ++ ++ prev_qlen -= sch->q.qlen; ++ prev_backlog -= sch->qstats.backlog; ++ b->drop_overlimit += prev_qlen; + +- if (same_flow) +- return NET_XMIT_CN; ++ if (same_flow) { ++ qdisc_tree_reduce_backlog(sch, prev_qlen - 1, ++ prev_backlog - len); ++ return NET_XMIT_CN; + } ++ qdisc_tree_reduce_backlog(sch, prev_qlen, prev_backlog); + return NET_XMIT_SUCCESS; + } + +-- +2.51.0 + diff --git a/queue-6.6/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch b/queue-6.6/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch new file mode 100644 index 0000000000..93a7224605 --- /dev/null +++ b/queue-6.6/net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch @@ -0,0 +1,66 @@ +From c1529922ee03ca5646146f870f11cbb705e3f05c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 10:43:27 +0000 +Subject: net: stmmac: fix rx limit check in stmmac_rx_zc() + +From: Alexey Kodanev + +[ Upstream commit 8048168df56e225c94e50b04cb7b0514135d7a1c ] + +The extra "count >= limit" check in stmmac_rx_zc() is redundant and +has no effect because the value of "count" doesn't change after the +while condition at this point. + +However, it can change after "read_again:" label: + + while (count < limit) { + ... + + if (count >= limit) + break; + read_again: + ... + /* XSK pool expects RX frame 1:1 mapped to XSK buffer */ + if (likely(status & rx_not_ls)) { + xsk_buff_free(buf->xdp); + buf->xdp = NULL; + dirty++; + count++; + goto read_again; + } + ... + +This patch addresses the same issue previously resolved in stmmac_rx() +by commit fa02de9e7588 ("net: stmmac: fix rx budget limit check"). +The fix is the same: move the check after the label to ensure that it +bounds the goto loop. + +Fixes: bba2556efad6 ("net: stmmac: Enable RX via AF_XDP zero-copy") +Signed-off-by: Alexey Kodanev +Reviewed-by: Russell King (Oracle) +Link: https://patch.msgid.link/20251126104327.175590-1-aleksei.kodanev@bell-sw.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +index 56a61599d0b6f..255c959886752 100644 +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -5141,10 +5141,10 @@ static int stmmac_rx_zc(struct stmmac_priv *priv, int limit, u32 queue) + len = 0; + } + ++read_again: + if (count >= limit) + break; + +-read_again: + buf1_len = 0; + entry = next_entry; + buf = &rx_q->buf_pool[entry]; +-- +2.51.0 + diff --git a/queue-6.6/netfilter-flowtable-check-for-maximum-number-of-enca.patch b/queue-6.6/netfilter-flowtable-check-for-maximum-number-of-enca.patch new file mode 100644 index 0000000000..afe8fe56a6 --- /dev/null +++ b/queue-6.6/netfilter-flowtable-check-for-maximum-number-of-enca.patch @@ -0,0 +1,48 @@ +From bffdad8f2c78979490784e00201332a92715077a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 23:26:22 +0000 +Subject: netfilter: flowtable: check for maximum number of encapsulations in + bridge vlan + +From: Pablo Neira Ayuso + +[ Upstream commit 634f3853cc98d73bdec8918010ee29b06981583e ] + +Add a sanity check to skip path discovery if the maximum number of +encapsulation is reached. While at it, check for underflow too. + +Fixes: 26267bf9bb57 ("netfilter: flowtable: bridge vlan hardware offload and switchdev") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nft_flow_offload.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c +index 1894032a7971c..75dddcaa9aa37 100644 +--- a/net/netfilter/nft_flow_offload.c ++++ b/net/netfilter/nft_flow_offload.c +@@ -140,12 +140,19 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack, + info->ingress_vlans |= BIT(info->num_encaps - 1); + break; + case DEV_PATH_BR_VLAN_TAG: ++ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) { ++ info->indev = NULL; ++ break; ++ } + info->encap[info->num_encaps].id = path->bridge.vlan_id; + info->encap[info->num_encaps].proto = path->bridge.vlan_proto; + info->num_encaps++; + break; + case DEV_PATH_BR_VLAN_UNTAG: +- info->num_encaps--; ++ if (WARN_ON_ONCE(info->num_encaps-- == 0)) { ++ info->indev = NULL; ++ break; ++ } + break; + case DEV_PATH_BR_VLAN_KEEP: + break; +-- +2.51.0 + diff --git a/queue-6.6/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch b/queue-6.6/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch new file mode 100644 index 0000000000..41cc554074 --- /dev/null +++ b/queue-6.6/netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch @@ -0,0 +1,503 @@ +From f39f7b3603a0ca36f18cac6a20fa37cfb791aece Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:30 +0100 +Subject: netfilter: nf_conncount: rework API to use sk_buff directly + +From: Fernando Fernandez Mancera + +[ Upstream commit be102eb6a0e7c03db00e50540622f4e43b2d2844 ] + +When using nf_conncount infrastructure for non-confirmed connections a +duplicated track is possible due to an optimization introduced since +commit d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC"). + +In order to fix this introduce a new conncount API that receives +directly an sk_buff struct. It fetches the tuple and zone and the +corresponding ct from it. It comes with both existing conncount variants +nf_conncount_count_skb() and nf_conncount_add_skb(). In addition remove +the old API and adjust all the users to use the new one. + +This way, for each sk_buff struct it is possible to check if there is a +ct present and already confirmed. If so, skip the add operation. + +Fixes: d265929930e2 ("netfilter: nf_conncount: reduce unnecessary GC") +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_conntrack_count.h | 17 +- + net/netfilter/nf_conncount.c | 177 ++++++++++++++------- + net/netfilter/nft_connlimit.c | 21 +-- + net/netfilter/xt_connlimit.c | 14 +- + net/openvswitch/conntrack.c | 16 +- + 5 files changed, 142 insertions(+), 103 deletions(-) + +diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h +index e227d997fc716..115bb7e572f7d 100644 +--- a/include/net/netfilter/nf_conntrack_count.h ++++ b/include/net/netfilter/nf_conntrack_count.h +@@ -20,15 +20,14 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family + void nf_conncount_destroy(struct net *net, unsigned int family, + struct nf_conncount_data *data); + +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); +- +-int nf_conncount_add(struct net *net, struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone); ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key); ++ ++int nf_conncount_add_skb(struct net *net, const struct sk_buff *skb, ++ u16 l3num, struct nf_conncount_list *list); + + void nf_conncount_list_init(struct nf_conncount_list *list); + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 6156c0751056c..7a8a6f72ff198 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -122,15 +122,65 @@ find_or_evict(struct net *net, struct nf_conncount_list *list, + return ERR_PTR(-EAGAIN); + } + ++static bool get_ct_or_tuple_from_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conn **ct, ++ struct nf_conntrack_tuple *tuple, ++ const struct nf_conntrack_zone **zone, ++ bool *refcounted) ++{ ++ const struct nf_conntrack_tuple_hash *h; ++ enum ip_conntrack_info ctinfo; ++ struct nf_conn *found_ct; ++ ++ found_ct = nf_ct_get(skb, &ctinfo); ++ if (found_ct && !nf_ct_is_template(found_ct)) { ++ *tuple = found_ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ *zone = nf_ct_zone(found_ct); ++ *ct = found_ct; ++ return true; ++ } ++ ++ if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), l3num, net, tuple)) ++ return false; ++ ++ if (found_ct) ++ *zone = nf_ct_zone(found_ct); ++ ++ h = nf_conntrack_find_get(net, *zone, tuple); ++ if (!h) ++ return true; ++ ++ found_ct = nf_ct_tuplehash_to_ctrack(h); ++ *refcounted = true; ++ *ct = found_ct; ++ ++ return true; ++} ++ + static int __nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + const struct nf_conntrack_tuple_hash *found; + struct nf_conncount_tuple *conn, *conn_n; ++ struct nf_conntrack_tuple tuple; ++ struct nf_conn *ct = NULL; + struct nf_conn *found_ct; + unsigned int collect = 0; ++ bool refcounted = false; ++ ++ if (!get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) ++ return -ENOENT; ++ ++ if (ct && nf_ct_is_confirmed(ct)) { ++ if (refcounted) ++ nf_ct_put(ct); ++ return 0; ++ } + + if ((u32)jiffies == list->last_gc) + goto add_new_node; +@@ -144,10 +194,10 @@ static int __nf_conncount_add(struct net *net, + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) +- return 0; /* already exists */ ++ goto out_put; /* already exists */ + } else { + collect++; + } +@@ -156,7 +206,7 @@ static int __nf_conncount_add(struct net *net, + + found_ct = nf_ct_tuplehash_to_ctrack(found); + +- if (nf_ct_tuple_equal(&conn->tuple, tuple) && ++ if (nf_ct_tuple_equal(&conn->tuple, &tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { + /* + * We should not see tuples twice unless someone hooks +@@ -165,7 +215,7 @@ static int __nf_conncount_add(struct net *net, + * Attempt to avoid a re-add in this case. + */ + nf_ct_put(found_ct); +- return 0; ++ goto out_put; + } else if (already_closed(found_ct)) { + /* + * we do not care about connections which are +@@ -188,31 +238,35 @@ static int __nf_conncount_add(struct net *net, + if (conn == NULL) + return -ENOMEM; + +- conn->tuple = *tuple; ++ conn->tuple = tuple; + conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; + list_add_tail(&conn->node, &list->head); + list->count++; + list->last_gc = (u32)jiffies; ++ ++out_put: ++ if (refcounted) ++ nf_ct_put(ct); + return 0; + } + +-int nf_conncount_add(struct net *net, +- struct nf_conncount_list *list, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++int nf_conncount_add_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_list *list) + { + int ret; + + /* check the saved connections */ + spin_lock_bh(&list->list_lock); +- ret = __nf_conncount_add(net, list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, list); + spin_unlock_bh(&list->list_lock); + + return ret; + } +-EXPORT_SYMBOL_GPL(nf_conncount_add); ++EXPORT_SYMBOL_GPL(nf_conncount_add_skb); + + void nf_conncount_list_init(struct nf_conncount_list *list) + { +@@ -309,19 +363,22 @@ static void schedule_gc_worker(struct nf_conncount_data *data, int tree) + + static unsigned int + insert_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, + struct rb_root *root, + unsigned int hash, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct nf_conncount_rb *gc_nodes[CONNCOUNT_GC_MAX_NODES]; ++ const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; ++ bool do_gc = true, refcounted = false; ++ unsigned int count = 0, gc_count = 0; + struct rb_node **rbnode, *parent; +- struct nf_conncount_rb *rbconn; ++ struct nf_conntrack_tuple tuple; + struct nf_conncount_tuple *conn; +- unsigned int count = 0, gc_count = 0; +- bool do_gc = true; ++ struct nf_conncount_rb *rbconn; ++ struct nf_conn *ct = NULL; + + spin_lock_bh(&nf_conncount_locks[hash]); + restart: +@@ -340,7 +397,7 @@ insert_tree(struct net *net, + } else { + int ret; + +- ret = nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); + if (ret) + count = 0; /* hotdrop */ + else +@@ -364,30 +421,35 @@ insert_tree(struct net *net, + goto restart; + } + +- /* expected case: match, insert new node */ +- rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); +- if (rbconn == NULL) +- goto out_unlock; ++ if (get_ct_or_tuple_from_skb(net, skb, l3num, &ct, &tuple, &zone, &refcounted)) { ++ /* expected case: match, insert new node */ ++ rbconn = kmem_cache_alloc(conncount_rb_cachep, GFP_ATOMIC); ++ if (rbconn == NULL) ++ goto out_unlock; + +- conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); +- if (conn == NULL) { +- kmem_cache_free(conncount_rb_cachep, rbconn); +- goto out_unlock; +- } ++ conn = kmem_cache_alloc(conncount_conn_cachep, GFP_ATOMIC); ++ if (conn == NULL) { ++ kmem_cache_free(conncount_rb_cachep, rbconn); ++ goto out_unlock; ++ } + +- conn->tuple = *tuple; +- conn->zone = *zone; +- conn->cpu = raw_smp_processor_id(); +- conn->jiffies32 = (u32)jiffies; +- memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ conn->tuple = tuple; ++ conn->zone = *zone; ++ conn->cpu = raw_smp_processor_id(); ++ conn->jiffies32 = (u32)jiffies; ++ memcpy(rbconn->key, key, sizeof(u32) * data->keylen); ++ ++ nf_conncount_list_init(&rbconn->list); ++ list_add(&conn->node, &rbconn->list.head); ++ count = 1; ++ rbconn->list.count = count; + +- nf_conncount_list_init(&rbconn->list); +- list_add(&conn->node, &rbconn->list.head); +- count = 1; +- rbconn->list.count = count; ++ rb_link_node_rcu(&rbconn->node, parent, rbnode); ++ rb_insert_color(&rbconn->node, root); + +- rb_link_node_rcu(&rbconn->node, parent, rbnode); +- rb_insert_color(&rbconn->node, root); ++ if (refcounted) ++ nf_ct_put(ct); ++ } + out_unlock: + spin_unlock_bh(&nf_conncount_locks[hash]); + return count; +@@ -395,10 +457,10 @@ insert_tree(struct net *net, + + static unsigned int + count_tree(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, + struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++ const u32 *key) + { + struct rb_root *root; + struct rb_node *parent; +@@ -422,7 +484,7 @@ count_tree(struct net *net, + } else { + int ret; + +- if (!tuple) { ++ if (!skb) { + nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; + } +@@ -437,7 +499,7 @@ count_tree(struct net *net, + } + + /* same source network -> be counted! */ +- ret = __nf_conncount_add(net, &rbconn->list, tuple, zone); ++ ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); + if (ret) + return 0; /* hotdrop */ +@@ -446,10 +508,10 @@ count_tree(struct net *net, + } + } + +- if (!tuple) ++ if (!skb) + return 0; + +- return insert_tree(net, data, root, hash, key, tuple, zone); ++ return insert_tree(net, skb, l3num, data, root, hash, key); + } + + static void tree_gc_worker(struct work_struct *work) +@@ -511,18 +573,19 @@ static void tree_gc_worker(struct work_struct *work) + } + + /* Count and return number of conntrack entries in 'net' with particular 'key'. +- * If 'tuple' is not null, insert it into the accounting data structure. +- * Call with RCU read lock. ++ * If 'skb' is not null, insert the corresponding tuple into the accounting ++ * data structure. Call with RCU read lock. + */ +-unsigned int nf_conncount_count(struct net *net, +- struct nf_conncount_data *data, +- const u32 *key, +- const struct nf_conntrack_tuple *tuple, +- const struct nf_conntrack_zone *zone) ++unsigned int nf_conncount_count_skb(struct net *net, ++ const struct sk_buff *skb, ++ u16 l3num, ++ struct nf_conncount_data *data, ++ const u32 *key) + { +- return count_tree(net, data, key, tuple, zone); ++ return count_tree(net, skb, l3num, data, key); ++ + } +-EXPORT_SYMBOL_GPL(nf_conncount_count); ++EXPORT_SYMBOL_GPL(nf_conncount_count_skb); + + struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family, + unsigned int keylen) +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index 92b984fa8175c..d998e27713ac7 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -24,26 +24,11 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + const struct nft_pktinfo *pkt, + const struct nft_set_ext *ext) + { +- const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; +- const struct nf_conntrack_tuple *tuple_ptr; +- struct nf_conntrack_tuple tuple; +- enum ip_conntrack_info ctinfo; +- const struct nf_conn *ct; + unsigned int count; ++ int err; + +- tuple_ptr = &tuple; +- +- ct = nf_ct_get(pkt->skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(pkt->skb, skb_network_offset(pkt->skb), +- nft_pf(pkt), nft_net(pkt), &tuple)) { +- regs->verdict.code = NF_DROP; +- return; +- } +- +- if (nf_conncount_add(nft_net(pkt), priv->list, tuple_ptr, zone)) { ++ err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); ++ if (err) { + regs->verdict.code = NF_DROP; + return; + } +diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c +index d1d0fa6c8061e..b3e4be6e1e436 100644 +--- a/net/netfilter/xt_connlimit.c ++++ b/net/netfilter/xt_connlimit.c +@@ -31,8 +31,6 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + { + struct net *net = xt_net(par); + const struct xt_connlimit_info *info = par->matchinfo; +- struct nf_conntrack_tuple tuple; +- const struct nf_conntrack_tuple *tuple_ptr = &tuple; + const struct nf_conntrack_zone *zone = &nf_ct_zone_dflt; + enum ip_conntrack_info ctinfo; + const struct nf_conn *ct; +@@ -40,13 +38,8 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + u32 key[5]; + + ct = nf_ct_get(skb, &ctinfo); +- if (ct != NULL) { +- tuple_ptr = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple; ++ if (ct) + zone = nf_ct_zone(ct); +- } else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), +- xt_family(par), net, &tuple)) { +- goto hotdrop; +- } + + if (xt_family(par) == NFPROTO_IPV6) { + const struct ipv6hdr *iph = ipv6_hdr(skb); +@@ -69,10 +62,9 @@ connlimit_mt(const struct sk_buff *skb, struct xt_action_param *par) + key[1] = zone->id; + } + +- connections = nf_conncount_count(net, info->data, key, tuple_ptr, +- zone); ++ connections = nf_conncount_count_skb(net, skb, xt_family(par), info->data, key); + if (connections == 0) +- /* kmalloc failed, drop it entirely */ ++ /* kmalloc failed or tuple couldn't be found, drop it entirely */ + goto hotdrop; + + return (connections > info->limit) ^ !!(info->flags & XT_CONNLIMIT_INVERT); +diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c +index 3b980bf2770bb..32485b3677375 100644 +--- a/net/openvswitch/conntrack.c ++++ b/net/openvswitch/conntrack.c +@@ -904,8 +904,8 @@ static u32 ct_limit_get(const struct ovs_ct_limit_info *info, u16 zone) + } + + static int ovs_ct_check_limit(struct net *net, +- const struct ovs_conntrack_info *info, +- const struct nf_conntrack_tuple *tuple) ++ const struct sk_buff *skb, ++ const struct ovs_conntrack_info *info) + { + struct ovs_net *ovs_net = net_generic(net, ovs_net_id); + const struct ovs_ct_limit_info *ct_limit_info = ovs_net->ct_limit_info; +@@ -918,8 +918,9 @@ static int ovs_ct_check_limit(struct net *net, + if (per_zone_limit == OVS_CT_LIMIT_UNLIMITED) + return 0; + +- connections = nf_conncount_count(net, ct_limit_info->data, +- &conncount_key, tuple, &info->zone); ++ connections = nf_conncount_count_skb(net, skb, info->family, ++ ct_limit_info->data, ++ &conncount_key); + if (connections > per_zone_limit) + return -ENOMEM; + +@@ -948,8 +949,7 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, + #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT) + if (static_branch_unlikely(&ovs_ct_limit_enabled)) { + if (!nf_ct_is_confirmed(ct)) { +- err = ovs_ct_check_limit(net, info, +- &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); ++ err = ovs_ct_check_limit(net, skb, info); + if (err) { + net_warn_ratelimited("openvswitch: zone: %u " + "exceeds conntrack limit\n", +@@ -1744,8 +1744,8 @@ static int __ovs_ct_limit_get_zone_limit(struct net *net, + zone_limit.limit = limit; + nf_ct_zone_init(&ct_zone, zone_id, NF_CT_DEFAULT_ZONE_DIR, 0); + +- zone_limit.count = nf_conncount_count(net, data, &conncount_key, NULL, +- &ct_zone); ++ zone_limit.count = nf_conncount_count_skb(net, NULL, 0, data, ++ &conncount_key); + return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit); + } + +-- +2.51.0 + diff --git a/queue-6.6/netfilter-nft_connlimit-update-the-count-if-add-was-.patch b/queue-6.6/netfilter-nft_connlimit-update-the-count-if-add-was-.patch new file mode 100644 index 0000000000..f4554579f3 --- /dev/null +++ b/queue-6.6/netfilter-nft_connlimit-update-the-count-if-add-was-.patch @@ -0,0 +1,105 @@ +From 7936a76b0f2c5985e3a6a168e3e674b932cf3d6d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 01:14:32 +0100 +Subject: netfilter: nft_connlimit: update the count if add was skipped + +From: Fernando Fernandez Mancera + +[ Upstream commit 69894e5b4c5e28cda5f32af33d4a92b7a4b93b0e ] + +Connlimit expression can be used for all kind of packets and not only +for packets with connection state new. See this ruleset as example: + +table ip filter { + chain input { + type filter hook input priority filter; policy accept; + tcp dport 22 ct count over 4 counter + } +} + +Currently, if the connection count goes over the limit the counter will +count the packets. When a connection is closed, the connection count +won't decrement as it should because it is only updated for new +connections due to an optimization on __nf_conncount_add() that prevents +updating the list if the connection is duplicated. + +To solve this problem, check whether the connection was skipped and if +so, update the list. Adjust count_tree() too so the same fix is applied +for xt_connlimit. + +Fixes: 976afca1ceba ("netfilter: nf_conncount: Early exit in nf_conncount_lookup() and cleanup") +Closes: https://lore.kernel.org/netfilter/trinity-85c72a88-d762-46c3-be97-36f10e5d9796-1761173693813@3c-app-mailcom-bs12/ +Signed-off-by: Fernando Fernandez Mancera +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Sasha Levin +--- + net/netfilter/nf_conncount.c | 12 ++++++++---- + net/netfilter/nft_connlimit.c | 13 +++++++++++-- + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c +index 7a8a6f72ff198..97b631a81484d 100644 +--- a/net/netfilter/nf_conncount.c ++++ b/net/netfilter/nf_conncount.c +@@ -179,7 +179,7 @@ static int __nf_conncount_add(struct net *net, + if (ct && nf_ct_is_confirmed(ct)) { + if (refcounted) + nf_ct_put(ct); +- return 0; ++ return -EEXIST; + } + + if ((u32)jiffies == list->last_gc) +@@ -398,7 +398,7 @@ insert_tree(struct net *net, + int ret; + + ret = nf_conncount_add_skb(net, skb, l3num, &rbconn->list); +- if (ret) ++ if (ret && ret != -EEXIST) + count = 0; /* hotdrop */ + else + count = rbconn->list.count; +@@ -501,10 +501,14 @@ count_tree(struct net *net, + /* same source network -> be counted! */ + ret = __nf_conncount_add(net, skb, l3num, &rbconn->list); + spin_unlock_bh(&rbconn->list.list_lock); +- if (ret) ++ if (ret && ret != -EEXIST) { + return 0; /* hotdrop */ +- else ++ } else { ++ /* -EEXIST means add was skipped, update the list */ ++ if (ret == -EEXIST) ++ nf_conncount_gc_list(net, &rbconn->list); + return rbconn->list.count; ++ } + } + } + +diff --git a/net/netfilter/nft_connlimit.c b/net/netfilter/nft_connlimit.c +index d998e27713ac7..83a7d5769396c 100644 +--- a/net/netfilter/nft_connlimit.c ++++ b/net/netfilter/nft_connlimit.c +@@ -29,8 +29,17 @@ static inline void nft_connlimit_do_eval(struct nft_connlimit *priv, + + err = nf_conncount_add_skb(nft_net(pkt), pkt->skb, nft_pf(pkt), priv->list); + if (err) { +- regs->verdict.code = NF_DROP; +- return; ++ if (err == -EEXIST) { ++ /* Call gc to update the list count if any connection has ++ * been closed already. This is useful for softlimit ++ * connections like limiting bandwidth based on a number ++ * of open connections. ++ */ ++ nf_conncount_gc_list(nft_net(pkt), priv->list); ++ } else { ++ regs->verdict.code = NF_DROP; ++ return; ++ } + } + + count = priv->list->count; +-- +2.51.0 + diff --git a/queue-6.6/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch b/queue-6.6/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch new file mode 100644 index 0000000000..395e458ead --- /dev/null +++ b/queue-6.6/nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch @@ -0,0 +1,48 @@ +From 63d49d42d6d9e01c1c2a00994bee38253873f8c2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 12:11:03 +0300 +Subject: NFSD/blocklayout: Fix minlength check in proc_layoutget + +From: Sergey Bashirov + +[ Upstream commit 3524b021b0ec620a76c89aee78e9d4b4130fb711 ] + +The extent returned by the file system may have a smaller offset than +the segment offset requested by the client. In this case, the minimum +segment length must be checked against the requested range. Otherwise, +the client may not be able to continue the read/write operation. + +Fixes: 8650b8a05850 ("nfsd: pNFS block layout driver") +Signed-off-by: Sergey Bashirov +Reviewed-by: Christoph Hellwig +Signed-off-by: Chuck Lever +Signed-off-by: Sasha Levin +--- + fs/nfsd/blocklayout.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c +index 59f119cce3dc6..3a9415fd77546 100644 +--- a/fs/nfsd/blocklayout.c ++++ b/fs/nfsd/blocklayout.c +@@ -23,6 +23,7 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + { + struct nfsd4_layout_seg *seg = &args->lg_seg; + struct super_block *sb = inode->i_sb; ++ u64 length; + u32 block_size = i_blocksize(inode); + struct pnfs_block_extent *bex; + struct iomap iomap; +@@ -53,7 +54,8 @@ nfsd4_block_proc_layoutget(struct inode *inode, const struct svc_fh *fhp, + goto out_error; + } + +- if (iomap.length < args->lg_minlength) { ++ length = iomap.offset + iomap.length - seg->offset; ++ if (length < args->lg_minlength) { + dprintk("pnfsd: extent smaller than minlength\n"); + goto out_layoutunavailable; + } +-- +2.51.0 + diff --git a/queue-6.6/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch b/queue-6.6/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch new file mode 100644 index 0000000000..6da8e76985 --- /dev/null +++ b/queue-6.6/ntfs3-fix-uninit-buffer-allocated-by-__getname.patch @@ -0,0 +1,36 @@ +From df8823e136b04df1b3788c6c6586f0c2a27e04cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 12:10:16 +0530 +Subject: ntfs3: Fix uninit buffer allocated by __getname() + +From: Sidharth Seela + +[ Upstream commit 9948dcb2f7b5a1bf8e8710eafaf6016e00be3ad6 ] + +Fix uninit errors caused after buffer allocation given to 'de'; by +initializing the buffer with zeroes. The fix was found by using KMSAN. + +Reported-by: syzbot+332bd4e9d148f11a87dc@syzkaller.appspotmail.com +Fixes: 78ab59fee07f2 ("fs/ntfs3: Rework file operations") +Signed-off-by: Sidharth Seela +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index a967babea8a59..f27e25776b730 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -1758,6 +1758,7 @@ int ntfs_link_inode(struct inode *inode, struct dentry *dentry) + de = __getname(); + if (!de) + return -ENOMEM; ++ memset(de, 0, PATH_MAX); + + /* Mark rw ntfs as dirty. It will be cleared at umount. */ + ntfs_set_state(sbi, NTFS_DIRTY_DIRTY); +-- +2.51.0 + diff --git a/queue-6.6/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch b/queue-6.6/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch new file mode 100644 index 0000000000..03dd280c0b --- /dev/null +++ b/queue-6.6/ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch @@ -0,0 +1,57 @@ +From 35a1757634fbf3dc2f0a913ae95f2b5a3e612a79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 12 Oct 2025 16:16:34 -0400 +Subject: ntfs3: fix uninit memory after failed mi_read in mi_format_new +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Raphael Pinsonneault-Thibeault + +[ Upstream commit 73e6b9dacf72a1e7a4265eacca46f8f33e0997d6 ] + +Fix a KMSAN un-init bug found by syzkaller. + +ntfs_get_bh() expects a buffer from sb_getblk(), that buffer may not be +uptodate. We do not bring the buffer uptodate before setting it as +uptodate. If the buffer were to not be uptodate, it could mean adding a +buffer with un-init data to the mi record. Attempting to load that record +will trigger KMSAN. + +Avoid this by setting the buffer as uptodate, if it’s not already, by +overwriting it. + +Reported-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=7a2ba6b7b66340cff225 +Tested-by: syzbot+7a2ba6b7b66340cff225@syzkaller.appspotmail.com +Fixes: 4342306f0f0d5 ("fs/ntfs3: Add file operations and implementation") +Signed-off-by: Raphael Pinsonneault-Thibeault +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/fsntfs.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c +index e19b13db4f91e..446079b0866d4 100644 +--- a/fs/ntfs3/fsntfs.c ++++ b/fs/ntfs3/fsntfs.c +@@ -1369,7 +1369,14 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, + } + if (buffer_locked(bh)) + __wait_on_buffer(bh); +- set_buffer_uptodate(bh); ++ ++ lock_buffer(bh); ++ if (!buffer_uptodate(bh)) ++ { ++ memset(bh->b_data, 0, blocksize); ++ set_buffer_uptodate(bh); ++ } ++ unlock_buffer(bh); + } else { + bh = ntfs_bread(sb, block); + if (!bh) { +-- +2.51.0 + diff --git a/queue-6.6/ntfs3-init-run-lock-for-extend-inode.patch b/queue-6.6/ntfs3-init-run-lock-for-extend-inode.patch new file mode 100644 index 0000000000..a642cc0d56 --- /dev/null +++ b/queue-6.6/ntfs3-init-run-lock-for-extend-inode.patch @@ -0,0 +1,57 @@ +From 9b88bb3e0cfcf1fe3814583b2ffd5234c82be1fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Sep 2025 13:50:13 +0800 +Subject: ntfs3: init run lock for extend inode + +From: Edward Adam Davis + +[ Upstream commit be99c62ac7e7af514e4b13f83c891a3cccefaa48 ] + +After setting the inode mode of $Extend to a regular file, executing the +truncate system call will enter the do_truncate() routine, causing the +run_lock uninitialized error reported by syzbot. + +Prior to patch 4e8011ffec79, if the inode mode of $Extend was not set to +a regular file, the do_truncate() routine would not be entered. + +Add the run_lock initialization when loading $Extend. + +syzbot reported: +INFO: trying to register non-static key. +Call Trace: + dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 + assign_lock_key+0x133/0x150 kernel/locking/lockdep.c:984 + register_lock_class+0x105/0x320 kernel/locking/lockdep.c:1299 + __lock_acquire+0x99/0xd20 kernel/locking/lockdep.c:5112 + lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868 + down_write+0x96/0x1f0 kernel/locking/rwsem.c:1590 + ntfs_set_size+0x140/0x200 fs/ntfs3/inode.c:860 + ntfs_extend+0x1d9/0x970 fs/ntfs3/file.c:387 + ntfs_setattr+0x2e8/0xbe0 fs/ntfs3/file.c:808 + +Fixes: 4e8011ffec79 ("ntfs3: pretend $Extend records as regular files") +Reported-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=bdeb22a4b9a09ab9aa45 +Tested-by: syzbot+bdeb22a4b9a09ab9aa45@syzkaller.appspotmail.com +Signed-off-by: Edward Adam Davis +Signed-off-by: Konstantin Komarov +Signed-off-by: Sasha Levin +--- + fs/ntfs3/inode.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c +index f27e25776b730..76326299ba368 100644 +--- a/fs/ntfs3/inode.c ++++ b/fs/ntfs3/inode.c +@@ -465,6 +465,7 @@ static struct inode *ntfs_read_mft(struct inode *inode, + /* Records in $Extend are not a files or general directories. */ + inode->i_op = &ntfs_file_inode_operations; + mode = S_IFREG; ++ init_rwsem(&ni->file.run_lock); + } else { + err = -EINVAL; + goto out; +-- +2.51.0 + diff --git a/queue-6.6/objtool-fix-standalone-hacks-jump_label.patch b/queue-6.6/objtool-fix-standalone-hacks-jump_label.patch new file mode 100644 index 0000000000..9773e4d1e4 --- /dev/null +++ b/queue-6.6/objtool-fix-standalone-hacks-jump_label.patch @@ -0,0 +1,44 @@ +From 00fa43d17ade493c13e657596f3432a187462c2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 23 Sep 2025 00:49:41 +0000 +Subject: objtool: Fix standalone --hacks=jump_label + +From: Dylan Hatch + +[ Upstream commit be8374a5ba7cbab6b97df94b4ffe0b92f5c8a6d2 ] + +The objtool command line 'objtool --hacks=jump_label foo.o' on its own +should be expected to rewrite jump labels to NOPs. This means the +add_special_section_alts() code path needs to run when only this option +is provided. + +This is mainly relevant in certain debugging situations, but could +potentially also fix kernel builds in which objtool is run with +--hacks=jump_label but without --orc, --stackval, --uaccess, or +--hacks=noinstr. + +Fixes: de6fbcedf5ab ("objtool: Read special sections with alts only when specific options are selected") +Signed-off-by: Dylan Hatch +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/check.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/objtool/check.c b/tools/objtool/check.c +index f8e676a6e6f8e..c021798ba8372 100644 +--- a/tools/objtool/check.c ++++ b/tools/objtool/check.c +@@ -2619,7 +2619,8 @@ static int decode_sections(struct objtool_file *file) + * Must be before add_jump_destinations(), which depends on 'func' + * being set for alternatives, to enable proper sibling call detection. + */ +- if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { ++ if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || ++ opts.hack_jump_label) { + ret = add_special_section_alts(file); + if (ret) + return ret; +-- +2.51.0 + diff --git a/queue-6.6/objtool-fix-weak-symbol-detection.patch b/queue-6.6/objtool-fix-weak-symbol-detection.patch new file mode 100644 index 0000000000..f475d8db98 --- /dev/null +++ b/queue-6.6/objtool-fix-weak-symbol-detection.patch @@ -0,0 +1,65 @@ +From 48a9a06d2fc15461a1ac2c00a4322483e9ba9a05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Sep 2025 09:03:27 -0700 +Subject: objtool: Fix weak symbol detection + +From: Josh Poimboeuf + +[ Upstream commit 72567c630d32bc31f671977f78228c80937ed80e ] + +find_symbol_hole_containing() fails to find a symbol hole (aka stripped +weak symbol) if its section has no symbols before the hole. This breaks +weak symbol detection if -ffunction-sections is enabled. + +Fix that by allowing the interval tree to contain section symbols, which +are always at offset zero for a given section. + +Fixes a bunch of (-ffunction-sections) warnings like: + + vmlinux.o: warning: objtool: .text.__x64_sys_io_setup+0x10: unreachable instruction + +Fixes: 4adb23686795 ("objtool: Ignore extra-symbol code") +Acked-by: Petr Mladek +Tested-by: Joe Lawrence +Signed-off-by: Josh Poimboeuf +Signed-off-by: Sasha Levin +--- + tools/objtool/elf.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c +index 081befa4674b8..797507a90251b 100644 +--- a/tools/objtool/elf.c ++++ b/tools/objtool/elf.c +@@ -110,7 +110,7 @@ struct symbol_hole { + }; + + /* +- * Find !section symbol where @offset is after it. ++ * Find the last symbol before @offset. + */ + static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + { +@@ -121,8 +121,7 @@ static int symbol_hole_by_offset(const void *key, const struct rb_node *node) + return -1; + + if (sh->key >= s->offset + s->len) { +- if (s->type != STT_SECTION) +- sh->sym = s; ++ sh->sym = s; + return 1; + } + +@@ -410,7 +409,8 @@ static void elf_add_symbol(struct elf *elf, struct symbol *sym) + sym->len = sym->sym.st_size; + + __sym_for_each(iter, &sym->sec->symbol_tree, sym->offset, sym->offset) { +- if (iter->offset == sym->offset && iter->type == sym->type) ++ if (iter->offset == sym->offset && iter->type == sym->type && ++ iter->len == sym->len) + iter->alias = sym; + } + +-- +2.51.0 + diff --git a/queue-6.6/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch b/queue-6.6/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch new file mode 100644 index 0000000000..38a87eb31c --- /dev/null +++ b/queue-6.6/ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch @@ -0,0 +1,51 @@ +From 1ee7be4acc49d356fab22b8a7e50b98fb423d8c8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 13:23:49 +0300 +Subject: ocfs2: relax BUG() to ocfs2_error() in __ocfs2_move_extent() + +From: Dmitry Antipov + +[ Upstream commit 8a7d58845fae061c62b50bc5eeb9bae4a1dedc3d ] + +In '__ocfs2_move_extent()', relax 'BUG()' to 'ocfs2_error()' just +to avoid crashing the whole kernel due to a filesystem corruption. + +Fixes: 8f603e567aa7 ("Ocfs2/move_extents: move a range of extent.") +Link: https://lkml.kernel.org/r/20251009102349.181126-2-dmantipov@yandex.ru +Signed-off-by: Dmitry Antipov +Closes: https://syzkaller.appspot.com/bug?extid=727d161855d11d81e411 +Reported-by: syzbot+727d161855d11d81e411@syzkaller.appspotmail.com +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Changwei Ge +Cc: Jun Piao +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + fs/ocfs2/move_extents.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c +index 2f34074f0078b..d97ec93ff4c26 100644 +--- a/fs/ocfs2/move_extents.c ++++ b/fs/ocfs2/move_extents.c +@@ -98,7 +98,13 @@ static int __ocfs2_move_extent(handle_t *handle, + + rec = &el->l_recs[index]; + +- BUG_ON(ext_flags != rec->e_flags); ++ if (ext_flags != rec->e_flags) { ++ ret = ocfs2_error(inode->i_sb, ++ "Inode %llu has corrupted extent %d with flags 0x%x at cpos %u\n", ++ (unsigned long long)ino, index, rec->e_flags, cpos); ++ goto out; ++ } ++ + /* + * after moving/defraging to new location, the extent is not going + * to be refcounted anymore. +-- +2.51.0 + diff --git a/queue-6.6/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch b/queue-6.6/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch new file mode 100644 index 0000000000..d9205b8b9a --- /dev/null +++ b/queue-6.6/pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch @@ -0,0 +1,44 @@ +From 590bf26a5ed4ffeb1cebf7227fa4453f074c55f4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 20:09:00 +0800 +Subject: PCI: dwc: Fix wrong PORT_LOGIC_LTSSM_STATE_MASK definition + +From: Shawn Lin + +[ Upstream commit bcc9a4a0bca3aee4303fa4a20302e57b24ac8f68 ] + +As per DesignWare Cores PCI Express Controller Databook, section 5.50, +SII: Debug Signals, cxpl_debug_info[63:0]: + + [5:0] smlh_ltssm_state: LTSSM current state. Encoding is same as the + dedicated smlh_ltssm_state output. + +The mask should be 6 bits, from 0 to 5. Hence, fix the mask definition. + +Fixes: 23fe5bd4be90 ("PCI: keystone: Cleanup ks_pcie_link_up()") +Signed-off-by: Shawn Lin +[mani: reworded description] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/1763122140-203068-1-git-send-email-shawn.lin@rock-chips.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pcie-designware.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h +index ef0b2efa9f93e..fec9473869bce 100644 +--- a/drivers/pci/controller/dwc/pcie-designware.h ++++ b/drivers/pci/controller/dwc/pcie-designware.h +@@ -92,7 +92,7 @@ + #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) + + #define PCIE_PORT_DEBUG0 0x728 +-#define PORT_LOGIC_LTSSM_STATE_MASK 0x1f ++#define PORT_LOGIC_LTSSM_STATE_MASK 0x3f + #define PORT_LOGIC_LTSSM_STATE_L0 0x11 + #define PCIE_PORT_DEBUG1 0x72C + #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) +-- +2.51.0 + diff --git a/queue-6.6/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch b/queue-6.6/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch new file mode 100644 index 0000000000..c801a086b3 --- /dev/null +++ b/queue-6.6/pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch @@ -0,0 +1,46 @@ +From 21274184f519ad8dbc04c438d30d7325753bb1a3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 13:34:51 +0530 +Subject: PCI: keystone: Exit ks_pcie_probe() for invalid mode + +From: Siddharth Vadapalli + +[ Upstream commit 95d9c3f0e4546eaec0977f3b387549a8463cd49f ] + +Commit under Fixes introduced support for PCIe EP mode on AM654x platforms. +When the mode happens to be either "DW_PCIE_RC_TYPE" or "DW_PCIE_EP_TYPE", +the PCIe Controller is configured accordingly. However, when the mode is +neither of them, an error message is displayed, but the driver probe +succeeds. Since this "invalid" mode is not associated with a functional +PCIe Controller, the probe should fail. + +Fix the behavior by exiting "ks_pcie_probe()" with the return value of +"-EINVAL" in addition to displaying the existing error message when the +mode is invalid. + +Fixes: 23284ad677a9 ("PCI: keystone: Add support for PCIe EP in AM654x Platforms") +Signed-off-by: Siddharth Vadapalli +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Bjorn Helgaas +Link: https://patch.msgid.link/20251029080547.1253757-4-s-vadapalli@ti.com +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/dwc/pci-keystone.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/pci/controller/dwc/pci-keystone.c b/drivers/pci/controller/dwc/pci-keystone.c +index 9055ce34c636b..7dcb9a9f385ee 100644 +--- a/drivers/pci/controller/dwc/pci-keystone.c ++++ b/drivers/pci/controller/dwc/pci-keystone.c +@@ -1341,6 +1341,8 @@ static int ks_pcie_probe(struct platform_device *pdev) + break; + default: + dev_err(dev, "INVALID device type %d\n", mode); ++ ret = -EINVAL; ++ goto err_get_sync; + } + + ks_pcie_enable_error_irq(ks_pcie); +-- +2.51.0 + diff --git a/queue-6.6/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch b/queue-6.6/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch new file mode 100644 index 0000000000..98a470cec8 --- /dev/null +++ b/queue-6.6/pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch @@ -0,0 +1,55 @@ +From ae55fb40ec588297c9062cc42dcde5c7732ee49d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 3 Oct 2025 10:35:34 +0200 +Subject: PCI: rcar-gen2: Drop ARM dependency from PCI_RCAR_GEN2 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Geert Uytterhoeven + +[ Upstream commit d312742f686582e6457070bcfd24bee8acfdf213 ] + +Since the reliance on ARM-specific struct pci_sys_data was removed, this +driver can be compile-tested on other architectures. + +While at it, make the help text a bit more generic, as some members of +the R-Car Gen2 family have a different number of internal PCI +controllers. + +Fixes: 4a957563fe0231e0 ("PCI: rcar-gen2: Convert to use modern host bridge probe functions") +Suggested-by: Ilpo Jarvinen +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Manivannan Sadhasivam +[bhelgaas: add rcar-gen2 to subject] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Ilpo Järvinen +Link: https://patch.msgid.link/00f75d6732eacce93f04ffaeedc415d2db714cd6.1759480426.git.geert+renesas@glider.be +Signed-off-by: Sasha Levin +--- + drivers/pci/controller/Kconfig | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig +index c0c3f28249907..7736817d5daba 100644 +--- a/drivers/pci/controller/Kconfig ++++ b/drivers/pci/controller/Kconfig +@@ -257,12 +257,11 @@ config PCIE_RCAR_EP + + config PCI_RCAR_GEN2 + bool "Renesas R-Car Gen2 Internal PCI controller" +- depends on ARCH_RENESAS || COMPILE_TEST +- depends on ARM ++ depends on (ARCH_RENESAS && ARM) || COMPILE_TEST + help + Say Y here if you want internal PCI support on R-Car Gen2 SoC. +- There are 3 internal PCI controllers available with a single +- built-in EHCI/OHCI host controller present on each one. ++ Each internal PCI controller contains a single built-in EHCI/OHCI ++ host controller. + + config PCIE_ROCKCHIP + bool +-- +2.51.0 + diff --git a/queue-6.6/perf-arm-spe-extend-branch-operations.patch b/queue-6.6/perf-arm-spe-extend-branch-operations.patch new file mode 100644 index 0000000000..53cbc4e661 --- /dev/null +++ b/queue-6.6/perf-arm-spe-extend-branch-operations.patch @@ -0,0 +1,94 @@ +From 2dcedb31ea280f76180a1fff477511df22cd1918 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Mar 2025 11:12:35 +0000 +Subject: perf arm-spe: Extend branch operations + +From: Leo Yan + +[ Upstream commit 64d86c03e1441742216b6332bdfabfb6ede31662 ] + +In Arm ARM (ARM DDI 0487, L.a), the section "D18.2.7 Operation Type +packet", the branch subclass is extended for Call Return (CR), Guarded +control stack data access (GCS). + +This commit adds support CR and GCS operations. The IND (indirect) +operation is defined only in bit [1], its macro is updated accordingly. + +Move the COND (Conditional) macro into the same group with other +operations for better maintenance. + +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Leo Yan +Link: https://lore.kernel.org/r/20250304111240.3378214-8-leo.yan@arm.com +Signed-off-by: Namhyung Kim +Stable-dep-of: 33e1fffea492 ("perf arm_spe: Fix memset subclass in operation") +Signed-off-by: Sasha Levin +--- + .../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c | 12 +++++++++--- + .../perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h | 11 ++++++++--- + 2 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index a454c6737563d..7b45fcf2454be 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -410,10 +410,16 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + + if (payload & SPE_OP_PKT_COND) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " COND"); +- +- if (SPE_OP_PKT_IS_INDIRECT_BRANCH(payload)) ++ if (payload & SPE_OP_PKT_INDIRECT_BRANCH) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " IND"); +- ++ if (payload & SPE_OP_PKT_GCS) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " GCS"); ++ if (SPE_OP_PKT_CR_BL(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-BL"); ++ if (SPE_OP_PKT_CR_RET(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-RET"); ++ if (SPE_OP_PKT_CR_NON_BL_RET(payload)) ++ arm_spe_pkt_out_string(&err, &buf, &buf_len, " CR-NON-BL-RET"); + break; + default: + /* Unknown index */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index 464a912b221cd..32d760ede7013 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -7,6 +7,7 @@ + #ifndef INCLUDE__ARM_SPE_PKT_DECODER_H__ + #define INCLUDE__ARM_SPE_PKT_DECODER_H__ + ++#include + #include + #include + +@@ -116,8 +117,6 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_COND BIT(0) +- + #define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) + #define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 + #define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +@@ -148,7 +147,13 @@ enum arm_spe_events { + #define SPE_OP_PKT_SVE_PRED BIT(2) + #define SPE_OP_PKT_SVE_FP BIT(1) + +-#define SPE_OP_PKT_IS_INDIRECT_BRANCH(v) (((v) & GENMASK_ULL(7, 1)) == 0x2) ++#define SPE_OP_PKT_CR_MASK GENMASK_ULL(4, 3) ++#define SPE_OP_PKT_CR_BL(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 1) ++#define SPE_OP_PKT_CR_RET(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 2) ++#define SPE_OP_PKT_CR_NON_BL_RET(v) (FIELD_GET(SPE_OP_PKT_CR_MASK, (v)) == 3) ++#define SPE_OP_PKT_GCS BIT(2) ++#define SPE_OP_PKT_INDIRECT_BRANCH BIT(1) ++#define SPE_OP_PKT_COND BIT(0) + + const char *arm_spe_pkt_name(enum arm_spe_pkt_type); + +-- +2.51.0 + diff --git a/queue-6.6/perf-arm_spe-fix-memset-subclass-in-operation.patch b/queue-6.6/perf-arm_spe-fix-memset-subclass-in-operation.patch new file mode 100644 index 0000000000..84c8f4e887 --- /dev/null +++ b/queue-6.6/perf-arm_spe-fix-memset-subclass-in-operation.patch @@ -0,0 +1,99 @@ +From 5965ff7220b856140383aa1d785deae57634cc11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 18:24:27 +0000 +Subject: perf arm_spe: Fix memset subclass in operation + +From: Leo Yan + +[ Upstream commit 33e1fffea492b7158a168914dc0da6aedf78d08e ] + +The operation subclass is extracted from bits [7..1] of the payload. +Since bit [0] is not parsed, there is no chance to match the memset type +(0x25). As a result, the memset payload is never parsed successfully. + +Instead of extracting a unified bit field, change to extract the +specific bits for each operation subclass. + +Fixes: 34fb60400e32 ("perf arm-spe: Add raw decoding for SPEv1.3 MTE and MOPS load/store") +Signed-off-by: Leo Yan +Reviewed-by: Ian Rogers +Reviewed-by: James Clark +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + .../arm-spe-decoder/arm-spe-pkt-decoder.c | 25 ++++++------------- + .../arm-spe-decoder/arm-spe-pkt-decoder.h | 15 ++++++----- + 2 files changed, 14 insertions(+), 26 deletions(-) + +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +index 7b45fcf2454be..573e7447fb422 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.c +@@ -368,31 +368,20 @@ static int arm_spe_pkt_desc_op_type(const struct arm_spe_pkt *packet, + arm_spe_pkt_out_string(&err, &buf, &buf_len, " AR"); + } + +- switch (SPE_OP_PKT_LDST_SUBCLASS_GET(payload)) { +- case SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP: ++ if (SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " SIMD-FP"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_GP_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_GP_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " GP-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " UNSPEC-REG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " NV-SYSREG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MTE-TAG"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMCPY: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMCPY"); +- break; +- case SPE_OP_PKT_LDST_SUBCLASS_MEMSET: ++ else if (SPE_OP_PKT_LDST_SUBCLASS_MEMSET(payload)) + arm_spe_pkt_out_string(&err, &buf, &buf_len, " MEMSET"); +- break; +- default: +- break; +- } + + if (SPE_OP_PKT_IS_LDST_SVE(payload)) { + /* SVE effective vector length */ +diff --git a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +index 32d760ede7013..0d947df9dd6ec 100644 +--- a/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h ++++ b/tools/perf/util/arm-spe-decoder/arm-spe-pkt-decoder.h +@@ -117,14 +117,13 @@ enum arm_spe_events { + + #define SPE_OP_PKT_IS_OTHER_SVE_OP(v) (((v) & (BIT(7) | BIT(3) | BIT(0))) == 0x8) + +-#define SPE_OP_PKT_LDST_SUBCLASS_GET(v) ((v) & GENMASK_ULL(7, 1)) +-#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG 0x0 +-#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP 0x4 +-#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG 0x10 +-#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG 0x30 +-#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG 0x14 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY 0x20 +-#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET 0x25 ++#define SPE_OP_PKT_LDST_SUBCLASS_GP_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x0) ++#define SPE_OP_PKT_LDST_SUBCLASS_SIMD_FP(v) (((v) & GENMASK_ULL(7, 1)) == 0x4) ++#define SPE_OP_PKT_LDST_SUBCLASS_UNSPEC_REG(v) (((v) & GENMASK_ULL(7, 1)) == 0x10) ++#define SPE_OP_PKT_LDST_SUBCLASS_NV_SYSREG(v) (((v) & GENMASK_ULL(7, 1)) == 0x30) ++#define SPE_OP_PKT_LDST_SUBCLASS_MTE_TAG(v) (((v) & GENMASK_ULL(7, 1)) == 0x14) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMCPY(v) (((v) & GENMASK_ULL(7, 1)) == 0x20) ++#define SPE_OP_PKT_LDST_SUBCLASS_MEMSET(v) (((v) & GENMASK_ULL(7, 0)) == 0x25) + + #define SPE_OP_PKT_IS_LDST_ATOMIC(v) (((v) & (GENMASK_ULL(7, 5) | BIT(1))) == 0x2) + +-- +2.51.0 + diff --git a/queue-6.6/perf-lock-contention-load-kernel-map-before-lookup.patch b/queue-6.6/perf-lock-contention-load-kernel-map-before-lookup.patch new file mode 100644 index 0000000000..bee6e91696 --- /dev/null +++ b/queue-6.6/perf-lock-contention-load-kernel-map-before-lookup.patch @@ -0,0 +1,56 @@ +From 082fada63cc4a01f85eaf8823f99fbb9ca10e055 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 21:01:39 -0700 +Subject: perf lock contention: Load kernel map before lookup + +From: Namhyung Kim + +[ Upstream commit 553d18c98a896094b99a01765b9698b204183d49 ] + +On some machines, it caused troubles when it tried to find kernel +symbols. I think it's because kernel modules and kallsyms are messed +up during load and split. + +Basically we want to make sure the kernel map is loaded and the code has +it in the lock_contention_read(). But recently we added more lookups in +the lock_contention_prepare() which is called before _read(). + +Also the kernel map (kallsyms) may not be the first one in the group +like on ARM. Let's use machine__kernel_map() rather than just loading +the first map. + +Reviewed-by: Ian Rogers +Fixes: 688d2e8de231c54e ("perf lock contention: Add -l/--lock-addr option") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_lock_contention.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c +index a73f39540a3d4..aa4c7baf20f57 100644 +--- a/tools/perf/util/bpf_lock_contention.c ++++ b/tools/perf/util/bpf_lock_contention.c +@@ -24,6 +24,9 @@ int lock_contention_prepare(struct lock_contention *con) + struct evlist *evlist = con->evlist; + struct target *target = con->target; + ++ /* make sure it loads the kernel map before lookup */ ++ map__load(machine__kernel_map(con->machine)); ++ + skel = lock_contention_bpf__open(); + if (!skel) { + pr_err("Failed to open lock-contention BPF skeleton\n"); +@@ -284,9 +287,6 @@ int lock_contention_read(struct lock_contention *con) + bpf_prog_test_run_opts(prog_fd, &opts); + } + +- /* make sure it loads the kernel map */ +- maps__load_first(machine->kmaps); +- + prev_key = NULL; + while (!bpf_map_get_next_key(fd, prev_key, &key)) { + s64 ls_key; +-- +2.51.0 + diff --git a/queue-6.6/perf-maps-add-maps__load_first.patch b/queue-6.6/perf-maps-add-maps__load_first.patch new file mode 100644 index 0000000000..24348a16b1 --- /dev/null +++ b/queue-6.6/perf-maps-add-maps__load_first.patch @@ -0,0 +1,106 @@ +From a0c1328f44b9b35ee21db6d7b52cf7aa5b9b8d02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 6 Dec 2023 17:16:53 -0800 +Subject: perf maps: Add maps__load_first() + +From: Ian Rogers + +[ Upstream commit e77b0236cd0cd1572c6a9b25097b207eab799e74 ] + +Avoid bpf_lock_contention_read touching the internal maps data structure +by adding a helper function. As access is done directly on the map in +maps, hold the read lock to stop it being removed. + +Signed-off-by: Ian Rogers +Cc: Adrian Hunter +Cc: Alexander Shishkin +Cc: Andi Kleen +Cc: Athira Rajeev +Cc: Changbin Du +Cc: Colin Ian King +Cc: Dmitrii Dolgov <9erthalion6@gmail.com> +Cc: German Gomez +Cc: Guilherme Amadio +Cc: Huacai Chen +Cc: Ingo Molnar +Cc: James Clark +Cc: Jiri Olsa +Cc: K Prateek Nayak +Cc: Kajol Jain +Cc: Kan Liang +Cc: Leo Yan +Cc: Li Dong +Cc: Liam Howlett +Cc: Mark Rutland +Cc: Masami Hiramatsu +Cc: Miguel Ojeda +Cc: Ming Wang +Cc: Namhyung Kim +Cc: Nick Terrell +Cc: Paolo Bonzini +Cc: Peter Zijlstra +Cc: Ravi Bangoria +Cc: Sandipan Das +Cc: Sean Christopherson +Cc: Steinar H. Gunderson +Cc: Vincent Whitchurch +Cc: Wenyu Liu +Cc: Yang Jihong +Link: https://lore.kernel.org/r/20231207011722.1220634-20-irogers@google.com +Signed-off-by: Arnaldo Carvalho de Melo +Stable-dep-of: 553d18c98a89 ("perf lock contention: Load kernel map before lookup") +Signed-off-by: Sasha Levin +--- + tools/perf/util/bpf_lock_contention.c | 2 +- + tools/perf/util/maps.c | 13 +++++++++++++ + tools/perf/util/maps.h | 2 ++ + 3 files changed, 16 insertions(+), 1 deletion(-) + +diff --git a/tools/perf/util/bpf_lock_contention.c b/tools/perf/util/bpf_lock_contention.c +index e7dddf0127bce..a73f39540a3d4 100644 +--- a/tools/perf/util/bpf_lock_contention.c ++++ b/tools/perf/util/bpf_lock_contention.c +@@ -285,7 +285,7 @@ int lock_contention_read(struct lock_contention *con) + } + + /* make sure it loads the kernel map */ +- map__load(maps__first(machine->kmaps)->map); ++ maps__load_first(machine->kmaps); + + prev_key = NULL; + while (!bpf_map_get_next_key(fd, prev_key, &key)) { +diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c +index 9a011aed4b754..9c7618b7d5e92 100644 +--- a/tools/perf/util/maps.c ++++ b/tools/perf/util/maps.c +@@ -713,3 +713,16 @@ int maps__merge_in(struct maps *kmaps, struct map *new_map) + } + return err; + } ++ ++void maps__load_first(struct maps *maps) ++{ ++ struct map_rb_node *first; ++ ++ down_read(maps__lock(maps)); ++ ++ first = maps__first(maps); ++ if (first) ++ map__load(first->map); ++ ++ up_read(maps__lock(maps)); ++} +diff --git a/tools/perf/util/maps.h b/tools/perf/util/maps.h +index a689149be8c43..d9f65f9e6d092 100644 +--- a/tools/perf/util/maps.h ++++ b/tools/perf/util/maps.h +@@ -145,4 +145,6 @@ void __maps__sort_by_name(struct maps *maps); + + void maps__fixup_end(struct maps *maps); + ++void maps__load_first(struct maps *maps); ++ + #endif // __PERF_MAPS_H +-- +2.51.0 + diff --git a/queue-6.6/perf-record-skip-synthesize-event-when-open-evsel-fa.patch b/queue-6.6/perf-record-skip-synthesize-event-when-open-evsel-fa.patch new file mode 100644 index 0000000000..465aeb6c32 --- /dev/null +++ b/queue-6.6/perf-record-skip-synthesize-event-when-open-evsel-fa.patch @@ -0,0 +1,71 @@ +From e561cfb8675d7ffb1b61bada3219ddac07326347 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:50:43 +0800 +Subject: perf record: skip synthesize event when open evsel failed + +From: Shuai Xue + +[ Upstream commit 163e5f2b96632b7fb2eaa965562aca0dbdf9f996 ] + +When using perf record with the `--overwrite` option, a segmentation fault +occurs if an event fails to open. For example: + + perf record -e cycles-ct -F 1000 -a --overwrite + Error: + cycles-ct:H: PMU Hardware doesn't support sampling/overflow-interrupts. Try 'perf stat' + perf: Segmentation fault + #0 0x6466b6 in dump_stack debug.c:366 + #1 0x646729 in sighandler_dump_stack debug.c:378 + #2 0x453fd1 in sigsegv_handler builtin-record.c:722 + #3 0x7f8454e65090 in __restore_rt libc-2.32.so[54090] + #4 0x6c5671 in __perf_event__synthesize_id_index synthetic-events.c:1862 + #5 0x6c5ac0 in perf_event__synthesize_id_index synthetic-events.c:1943 + #6 0x458090 in record__synthesize builtin-record.c:2075 + #7 0x45a85a in __cmd_record builtin-record.c:2888 + #8 0x45deb6 in cmd_record builtin-record.c:4374 + #9 0x4e5e33 in run_builtin perf.c:349 + #10 0x4e60bf in handle_internal_command perf.c:401 + #11 0x4e6215 in run_argv perf.c:448 + #12 0x4e653a in main perf.c:555 + #13 0x7f8454e4fa72 in __libc_start_main libc-2.32.so[3ea72] + #14 0x43a3ee in _start ??:0 + +The --overwrite option implies --tail-synthesize, which collects non-sample +events reflecting the system status when recording finishes. However, when +evsel opening fails (e.g., unsupported event 'cycles-ct'), session->evlist +is not initialized and remains NULL. The code unconditionally calls +record__synthesize() in the error path, which iterates through the NULL +evlist pointer and causes a segfault. + +To fix it, move the record__synthesize() call inside the error check block, so +it's only called when there was no error during recording, ensuring that evlist +is properly initialized. + +Fixes: 4ea648aec019 ("perf record: Add --tail-synthesize option") +Signed-off-by: Shuai Xue +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/builtin-record.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c +index 81f77c0505fde..ddaf38f92898f 100644 +--- a/tools/perf/builtin-record.c ++++ b/tools/perf/builtin-record.c +@@ -2776,11 +2776,11 @@ static int __cmd_record(struct record *rec, int argc, const char **argv) + rec->bytes_written += off_cpu_write(rec->session); + + record__read_lost_samples(rec); +- record__synthesize(rec, true); + /* this will be recalculated during process_buildids() */ + rec->samples = 0; + + if (!err) { ++ record__synthesize(rec, true); + if (!rec->timestamp_filename) { + record__finish_output(rec); + } else { +-- +2.51.0 + diff --git a/queue-6.6/perf-tools-fix-split-kallsyms-dso-counting.patch b/queue-6.6/perf-tools-fix-split-kallsyms-dso-counting.patch new file mode 100644 index 0000000000..48f6f0b123 --- /dev/null +++ b/queue-6.6/perf-tools-fix-split-kallsyms-dso-counting.patch @@ -0,0 +1,41 @@ +From a9e3ca8d29c1d501e5458b67b90c7a458d1eb87f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 2 Dec 2025 15:57:15 -0800 +Subject: perf tools: Fix split kallsyms DSO counting + +From: Namhyung Kim + +[ Upstream commit ad0b9c4865b98dc37f4d606d26b1c19808796805 ] + +It's counted twice as it's increased after calling maps__insert(). I +guess we want to increase it only after it's added properly. + +Reviewed-by: Ian Rogers +Fixes: 2e538c4a1847291cf ("perf tools: Improve kernel/modules symbol lookup") +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/util/symbol.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c +index ea24f21aafc3e..18556b7a76563 100644 +--- a/tools/perf/util/symbol.c ++++ b/tools/perf/util/symbol.c +@@ -905,11 +905,11 @@ static int maps__split_kallsyms(struct maps *kmaps, struct dso *dso, u64 delta, + if (dso->kernel == DSO_SPACE__KERNEL_GUEST) + snprintf(dso_name, sizeof(dso_name), + "[guest.kernel].%d", +- kernel_range++); ++ kernel_range); + else + snprintf(dso_name, sizeof(dso_name), + "[kernel].%d", +- kernel_range++); ++ kernel_range); + + ndso = dso__new(dso_name); + if (ndso == NULL) +-- +2.51.0 + diff --git a/queue-6.6/perf-x86-intel-correct-large-pebs-flag-check.patch b/queue-6.6/perf-x86-intel-correct-large-pebs-flag-check.patch new file mode 100644 index 0000000000..db9f339566 --- /dev/null +++ b/queue-6.6/perf-x86-intel-correct-large-pebs-flag-check.patch @@ -0,0 +1,46 @@ +From ab290cadbce1b571c99779ed2b69c2a1a59b65f5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 18:21:28 +0800 +Subject: perf/x86/intel: Correct large PEBS flag check + +From: Dapeng Mi + +[ Upstream commit 5e4e355ae7cdeb0fef5dbe908866e1f895abfacc ] + +current large PEBS flag check only checks if sample_regs_user contains +unsupported GPRs but doesn't check if sample_regs_intr contains +unsupported GPRs. + +Of course, currently PEBS HW supports to sample all perf supported GPRs, +the missed check doesn't cause real issue. But it won't be true any more +after the subsequent patches support to sample SSP register. SSP +sampling is not supported by adaptive PEBS HW and it would be supported +until arch-PEBS HW. So correct this issue. + +Fixes: a47ba4d77e12 ("perf/x86: Enable free running PEBS for REGS_USER/INTR") +Signed-off-by: Dapeng Mi +Signed-off-by: Peter Zijlstra (Intel) +Link: https://patch.msgid.link/20251029102136.61364-5-dapeng1.mi@linux.intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/events/intel/core.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c +index 87ea4339e03a2..8d1ec1d888da7 100644 +--- a/arch/x86/events/intel/core.c ++++ b/arch/x86/events/intel/core.c +@@ -3808,7 +3808,9 @@ static unsigned long intel_pmu_large_pebs_flags(struct perf_event *event) + if (!event->attr.exclude_kernel) + flags &= ~PERF_SAMPLE_REGS_USER; + if (event->attr.sample_regs_user & ~PEBS_GP_REGS) +- flags &= ~(PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR); ++ flags &= ~PERF_SAMPLE_REGS_USER; ++ if (event->attr.sample_regs_intr & ~PEBS_GP_REGS) ++ flags &= ~PERF_SAMPLE_REGS_INTR; + return flags; + } + +-- +2.51.0 + diff --git a/queue-6.6/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch b/queue-6.6/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch new file mode 100644 index 0000000000..3285d662cb --- /dev/null +++ b/queue-6.6/phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch @@ -0,0 +1,64 @@ +From f9044b2f63d5cf4f0c0fe07ea254908a04b7dd05 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 21:13:50 +0200 +Subject: phy: mscc: Fix PTP for VSC8574 and VSC8572 + +From: Horatiu Vultur + +[ Upstream commit ea5df88aeca112aac69e6c32e3dd1433a113b0c9 ] + +The PTP initialization is two-step. First part are the function +vsc8584_ptp_probe_once() and vsc8584_ptp_probe() at probe time which +initialize the locks, queues, creates the PTP device. The second part is +the function vsc8584_ptp_init() at config_init() time which initialize +PTP in the HW. + +For VSC8574 and VSC8572, the PTP initialization is incomplete. It is +missing the first part but it makes the second part. Meaning that the +ptp_clock_register() is never called. + +There is no crash without the first part when enabling PTP but this is +unexpected because some PHys have PTP functionality exposed by the +driver and some don't even though they share the same PTP clock PTP. + +Fixes: 774626fa440e ("net: phy: mscc: Add PTP support for 2 more VSC PHYs") +Reviewed-by: Maxime Chevallier +Signed-off-by: Horatiu Vultur +Link: https://patch.msgid.link/20251023191350.190940-3-horatiu.vultur@microchip.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/mscc/mscc_main.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c +index 3a932b30f4358..0a4aa8e08827a 100644 +--- a/drivers/net/phy/mscc/mscc_main.c ++++ b/drivers/net/phy/mscc/mscc_main.c +@@ -2595,7 +2595,7 @@ static struct phy_driver vsc85xx_driver[] = { + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +@@ -2616,12 +2616,12 @@ static struct phy_driver vsc85xx_driver[] = { + .config_aneg = &vsc85xx_config_aneg, + .aneg_done = &genphy_aneg_done, + .read_status = &vsc85xx_read_status, +- .handle_interrupt = vsc85xx_handle_interrupt, ++ .handle_interrupt = vsc8584_handle_interrupt, + .config_intr = &vsc85xx_config_intr, + .suspend = &genphy_suspend, + .resume = &genphy_resume, + .remove = &vsc85xx_remove, +- .probe = &vsc8574_probe, ++ .probe = &vsc8584_probe, + .set_wol = &vsc85xx_wol_set, + .get_wol = &vsc85xx_wol_get, + .get_tunable = &vsc85xx_get_tunable, +-- +2.51.0 + diff --git a/queue-6.6/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch b/queue-6.6/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch new file mode 100644 index 0000000000..b554330aa8 --- /dev/null +++ b/queue-6.6/phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch @@ -0,0 +1,94 @@ +From 371fc01eeae9829ef81fde944c0dfee2105f58b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 16:58:05 +0300 +Subject: phy: renesas: rcar-gen3-usb2: Fix an error handling path in + rcar_gen3_phy_usb2_probe() + +From: Christophe JAILLET + +[ Upstream commit 662bb179d3381c7c069e44bb177396bcaee31cc8 ] + +If an error occurs after the reset_control_deassert(), +reset_control_assert() must be called, as already done in the remove +function. + +Use devm_add_action_or_reset() to add the missing call and simplify the +.remove() function accordingly. + +While at it, drop struct rcar_gen3_chan::rstc as it is not used aymore. + +[claudiu.beznea: removed "struct reset_control *rstc = data;" from + rcar_gen3_reset_assert(), dropped struct rcar_gen3_chan::rstc] + +Fixes: 4eae16375357 ("phy: renesas: rcar-gen3-usb2: Add support to initialize the bus") +Signed-off-by: Christophe JAILLET +Reviewed-by: Biju Das +Reviewed-by: Geert Uytterhoeven +Tested-by: Wolfram Sang +Signed-off-by: Claudiu Beznea +Link: https://patch.msgid.link/20251023135810.1688415-3-claudiu.beznea.uj@bp.renesas.com +Signed-off-by: Vinod Koul +Signed-off-by: Sasha Levin +--- + drivers/phy/renesas/phy-rcar-gen3-usb2.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/drivers/phy/renesas/phy-rcar-gen3-usb2.c b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +index 9a6391361a0be..89a9693c9f577 100644 +--- a/drivers/phy/renesas/phy-rcar-gen3-usb2.c ++++ b/drivers/phy/renesas/phy-rcar-gen3-usb2.c +@@ -117,7 +117,6 @@ struct rcar_gen3_chan { + struct extcon_dev *extcon; + struct rcar_gen3_phy rphys[NUM_OF_PHYS]; + struct regulator *vbus; +- struct reset_control *rstc; + struct work_struct work; + spinlock_t lock; /* protects access to hardware and driver data structure. */ + enum usb_dr_mode dr_mode; +@@ -658,21 +657,31 @@ static enum usb_dr_mode rcar_gen3_get_dr_mode(struct device_node *np) + return candidate; + } + ++static void rcar_gen3_reset_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int rcar_gen3_phy_usb2_init_bus(struct rcar_gen3_chan *channel) + { + struct device *dev = channel->dev; ++ struct reset_control *rstc; + int ret; + u32 val; + +- channel->rstc = devm_reset_control_array_get_shared(dev); +- if (IS_ERR(channel->rstc)) +- return PTR_ERR(channel->rstc); ++ rstc = devm_reset_control_array_get_shared(dev); ++ if (IS_ERR(rstc)) ++ return PTR_ERR(rstc); + + ret = pm_runtime_resume_and_get(dev); + if (ret) + return ret; + +- ret = reset_control_deassert(channel->rstc); ++ ret = reset_control_deassert(rstc); ++ if (ret) ++ goto rpm_put; ++ ++ ret = devm_add_action_or_reset(dev, rcar_gen3_reset_assert, rstc); + if (ret) + goto rpm_put; + +@@ -814,7 +823,6 @@ static void rcar_gen3_phy_usb2_remove(struct platform_device *pdev) + if (channel->is_otg_channel) + device_remove_file(&pdev->dev, &dev_attr_role); + +- reset_control_assert(channel->rstc); + pm_runtime_disable(&pdev->dev); + }; + +-- +2.51.0 + diff --git a/queue-6.6/pinctrl-single-fix-incorrect-type-for-error-return-v.patch b/queue-6.6/pinctrl-single-fix-incorrect-type-for-error-return-v.patch new file mode 100644 index 0000000000..8b2125df2e --- /dev/null +++ b/queue-6.6/pinctrl-single-fix-incorrect-type-for-error-return-v.patch @@ -0,0 +1,53 @@ +From 44b1034cbfbec3fa005b87b90b0424316daa75fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 3 Dec 2025 14:13:47 +0800 +Subject: pinctrl: single: Fix incorrect type for error return variable + +From: Haotian Zhang + +[ Upstream commit 61d1bb53547d42c6bdaec9da4496beb3a1a05264 ] + +pcs_pinconf_get() and pcs_pinconf_set() declare ret as unsigned int, +but assign it the return values of pcs_get_function() that may return +negative error codes. This causes negative error codes to be +converted to large positive values. + +Change ret from unsigned int to int in both functions. + +Fixes: 9dddb4df90d1 ("pinctrl: single: support generic pinconf") +Signed-off-by: Haotian Zhang +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 5c6d5add6ecac..2ee0ee3b6ed14 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -489,7 +489,8 @@ static int pcs_pinconf_get(struct pinctrl_dev *pctldev, + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; + enum pin_config_param param; +- unsigned offset = 0, data = 0, i, j, ret; ++ unsigned offset = 0, data = 0, i, j; ++ int ret; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) +@@ -553,9 +554,9 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + { + struct pcs_device *pcs = pinctrl_dev_get_drvdata(pctldev); + struct pcs_function *func; +- unsigned offset = 0, shift = 0, i, data, ret; ++ unsigned offset = 0, shift = 0, i, data; + u32 arg; +- int j; ++ int j, ret; + enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); +-- +2.51.0 + diff --git a/queue-6.6/pinctrl-single-fix-pin_config_bias_disable-handling.patch b/queue-6.6/pinctrl-single-fix-pin_config_bias_disable-handling.patch new file mode 100644 index 0000000000..e43ba03b35 --- /dev/null +++ b/queue-6.6/pinctrl-single-fix-pin_config_bias_disable-handling.patch @@ -0,0 +1,95 @@ +From a41bfe2f3dc6e30e471864e1d88fa01b0e332290 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 19 Mar 2024 12:06:34 +0100 +Subject: pinctrl: single: Fix PIN_CONFIG_BIAS_DISABLE handling + +From: Matthijs Kooijman + +[ Upstream commit b5fe46efc147516a908d2d31bf40eb858ab76d51 ] + +The pinctrl-single driver handles pin_config_set by looking up the +requested setting in a DT-defined lookup table, which defines what bits +correspond to each setting. There is no way to add +PIN_CONFIG_BIAS_DISABLE entries to the table, since there is instead +code to disable the bias by applying the disable values of both the +pullup and pulldown entries in the table. + +However, this code is inside the table-lookup loop, so it would only +execute if there is an entry for PIN_CONFIG_BIAS_DISABLE in the table, +which can never exist, so this code never runs. + +This commit lifts the offending code out of the loop, so it just +executes directly whenever PIN_CONFIG_BIAS_DISABLE is requested, +skippipng the table lookup loop. + +This also introduces a new `param` variable to make the code slightly +more readable. + +This bug seems to have existed when this code was first merged in commit +9dddb4df90d13 ("pinctrl: single: support generic pinconf"). Earlier +versions of this patch did have an entry for PIN_CONFIG_BIAS_DISABLE in +the lookup table, but that was removed, which is probably how this bug +was introduced. + +Signed-off-by: Matthijs Kooijman +Reviewed-by: Haojian Zhuang +Reviewed-by: Tony Lindgren +Message-ID: <20240319110633.230329-1-matthijs@stdin.nl> +Signed-off-by: Linus Walleij +Stable-dep-of: 61d1bb53547d ("pinctrl: single: Fix incorrect type for error return variable") +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 7684039be10cb..5c6d5add6ecac 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -556,21 +556,30 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + unsigned offset = 0, shift = 0, i, data, ret; + u32 arg; + int j; ++ enum pin_config_param param; + + ret = pcs_get_function(pctldev, pin, &func); + if (ret) + return ret; + + for (j = 0; j < num_configs; j++) { ++ param = pinconf_to_config_param(configs[j]); ++ ++ /* BIAS_DISABLE has no entry in the func->conf table */ ++ if (param == PIN_CONFIG_BIAS_DISABLE) { ++ /* This just disables all bias entries */ ++ pcs_pinconf_clear_bias(pctldev, pin); ++ continue; ++ } ++ + for (i = 0; i < func->nconfs; i++) { +- if (pinconf_to_config_param(configs[j]) +- != func->conf[i].param) ++ if (param != func->conf[i].param) + continue; + + offset = pin * (pcs->width / BITS_PER_BYTE); + data = pcs->read(pcs->base + offset); + arg = pinconf_to_config_argument(configs[j]); +- switch (func->conf[i].param) { ++ switch (param) { + /* 2 parameters */ + case PIN_CONFIG_INPUT_SCHMITT: + case PIN_CONFIG_DRIVE_STRENGTH: +@@ -582,9 +591,6 @@ static int pcs_pinconf_set(struct pinctrl_dev *pctldev, + data |= (arg << shift) & func->conf[i].mask; + break; + /* 4 parameters */ +- case PIN_CONFIG_BIAS_DISABLE: +- pcs_pinconf_clear_bias(pctldev, pin); +- break; + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_UP: + if (arg) { +-- +2.51.0 + diff --git a/queue-6.6/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.6/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..7173c68940 --- /dev/null +++ b/queue-6.6/pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,43 @@ +From a1bd1757c35eabab70bca14789e724f15cdd364c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 09:42:52 +0800 +Subject: pinctrl: stm32: fix hwspinlock resource leak in probe function + +From: Haotian Zhang + +[ Upstream commit 002679f79ed605e543fbace465557317cd307c9a ] + +In stm32_pctl_probe(), hwspin_lock_request_specific() is called to +request a hwspinlock, but the acquired lock is not freed on multiple +error paths after this call. This causes resource leakage when the +function fails to initialize properly. + +Use devm_hwspin_lock_request_specific() instead of +hwspin_lock_request_specific() to automatically manage the hwspinlock +resource lifecycle. + +Fixes: 97cfb6cd34f2 ("pinctrl: stm32: protect configuration registers with a hwspinlock") +Signed-off-by: Haotian Zhang +Reviewed-by: Antonio Borneo +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/stm32/pinctrl-stm32.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/stm32/pinctrl-stm32.c b/drivers/pinctrl/stm32/pinctrl-stm32.c +index 67c2791ee246f..ac96523e07b8d 100644 +--- a/drivers/pinctrl/stm32/pinctrl-stm32.c ++++ b/drivers/pinctrl/stm32/pinctrl-stm32.c +@@ -1550,7 +1550,7 @@ int stm32_pctl_probe(struct platform_device *pdev) + if (hwlock_id == -EPROBE_DEFER) + return hwlock_id; + } else { +- pctl->hwlock = hwspin_lock_request_specific(hwlock_id); ++ pctl->hwlock = devm_hwspin_lock_request_specific(dev, hwlock_id); + } + + spin_lock_init(&pctl->irqmux_lock); +-- +2.51.0 + diff --git a/queue-6.6/power-supply-apm_power-only-unset-own-apm_get_power_.patch b/queue-6.6/power-supply-apm_power-only-unset-own-apm_get_power_.patch new file mode 100644 index 0000000000..63ff3274df --- /dev/null +++ b/queue-6.6/power-supply-apm_power-only-unset-own-apm_get_power_.patch @@ -0,0 +1,42 @@ +From efb104f187d2c94112b9f0f6a8389c614ca66109 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 00:05:18 +0200 +Subject: power: supply: apm_power: only unset own apm_get_power_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ahelenia Ziemiańska + +[ Upstream commit bd44ea12919ac4e83c9f3997240fe58266aa8799 ] + +Mirroring drivers/macintosh/apm_emu.c, this means that + modprobe apm_power && modprobe $anotherdriver && modprobe -r apm_power +leaves $anotherdriver's apm_get_power_status instead of deleting it. + +Fixes: 3788ec932bfd ("[BATTERY] APM emulation driver for class batteries") +Signed-off-by: Ahelenia Ziemiańska +Link: https://patch.msgid.link/xczpgox57hxbunkcbdl5fxhc4gnsajsipldfidi7355afezk64@tarta.nabijaczleweli.xyz +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/apm_power.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/apm_power.c b/drivers/power/supply/apm_power.c +index 9d1a7fbcaed42..50b9636945599 100644 +--- a/drivers/power/supply/apm_power.c ++++ b/drivers/power/supply/apm_power.c +@@ -365,7 +365,8 @@ static int __init apm_battery_init(void) + + static void __exit apm_battery_exit(void) + { +- apm_get_power_status = NULL; ++ if (apm_get_power_status == apm_battery_apm_get_power_status) ++ apm_get_power_status = NULL; + } + + module_init(apm_battery_init); +-- +2.51.0 + diff --git a/queue-6.6/power-supply-cw2015-check-devm_delayed_work_autocanc.patch b/queue-6.6/power-supply-cw2015-check-devm_delayed_work_autocanc.patch new file mode 100644 index 0000000000..9b058b16dd --- /dev/null +++ b/queue-6.6/power-supply-cw2015-check-devm_delayed_work_autocanc.patch @@ -0,0 +1,46 @@ +From d0cacaaea518b9e7c630b87e300307e8984ca3d5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Oct 2025 15:07:11 +0300 +Subject: power: supply: cw2015: Check devm_delayed_work_autocancel() return + code + +From: Ivan Abramov + +[ Upstream commit 92ec7e7b86ec0aff9cd7db64d9dce50a0ea7c542 ] + +Since devm_delayed_work_autocancel() may fail, add return code check and +exit cw_bat_probe() on error. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 0cb172a4918e ("power: supply: cw2015: Use device managed API to simplify the code") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251008120711.556021-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/cw2015_battery.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/power/supply/cw2015_battery.c b/drivers/power/supply/cw2015_battery.c +index 434e3233c9f8c..f777665cf0687 100644 +--- a/drivers/power/supply/cw2015_battery.c ++++ b/drivers/power/supply/cw2015_battery.c +@@ -702,7 +702,13 @@ static int cw_bat_probe(struct i2c_client *client) + if (!cw_bat->battery_workqueue) + return -ENOMEM; + +- devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ ret = devm_delayed_work_autocancel(&client->dev, &cw_bat->battery_delay_work, cw_bat_work); ++ if (ret) { ++ dev_err_probe(&client->dev, ret, ++ "Failed to register delayed work\n"); ++ return ret; ++ } ++ + queue_delayed_work(cw_bat->battery_workqueue, + &cw_bat->battery_delay_work, msecs_to_jiffies(10)); + return 0; +-- +2.51.0 + diff --git a/queue-6.6/power-supply-rt9467-prevent-using-uninitialized-loca.patch b/queue-6.6/power-supply-rt9467-prevent-using-uninitialized-loca.patch new file mode 100644 index 0000000000..aa198da467 --- /dev/null +++ b/queue-6.6/power-supply-rt9467-prevent-using-uninitialized-loca.patch @@ -0,0 +1,40 @@ +From dede64b4a5e6c8e181237709fcccb7d6a059c4fb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:53:08 +0300 +Subject: power: supply: rt9467: Prevent using uninitialized local variable in + rt9467_set_value_from_ranges() + +From: Murad Masimov + +[ Upstream commit 15aca30cc6c69806054b896a2ccf7577239cb878 ] + +There is a typo in rt9467_set_value_from_ranges() that can cause leaving local +variable sel with an undefined value which is then used in regmap_field_write(). + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Murad Masimov +Link: https://patch.msgid.link/20251009145308.1830893-1-m.masimov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index 1462d630e399c..1e16593267511 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -376,7 +376,7 @@ static int rt9467_set_value_from_ranges(struct rt9467_chg_data *data, + if (rsel == RT9467_RANGE_VMIVR) { + ret = linear_range_get_selector_high(range, value, &sel, &found); + if (ret) +- value = range->max_sel; ++ sel = range->max_sel; + } else { + linear_range_get_selector_within(range, value, &sel); + } +-- +2.51.0 + diff --git a/queue-6.6/power-supply-rt9467-return-error-on-failure-in-rt946.patch b/queue-6.6/power-supply-rt9467-return-error-on-failure-in-rt946.patch new file mode 100644 index 0000000000..12409b94b2 --- /dev/null +++ b/queue-6.6/power-supply-rt9467-return-error-on-failure-in-rt946.patch @@ -0,0 +1,44 @@ +From b02a60c61f8928103ee2ad46e65ba330c3f9e037 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 17:47:24 +0300 +Subject: power: supply: rt9467: Return error on failure in + rt9467_set_value_from_ranges() + +From: Ivan Abramov + +[ Upstream commit 8b27fe2d8d2380118c343629175385ff587e2fe4 ] + +The return value of rt9467_set_value_from_ranges() when setting AICL VTH is +not checked, even though it may fail. + +Log error and return from rt9467_run_aicl() on fail. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 6f7f70e3a8dd ("power: supply: rt9467: Add Richtek RT9467 charger driver") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009144725.562278-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/rt9467-charger.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/power/supply/rt9467-charger.c b/drivers/power/supply/rt9467-charger.c +index fdfdc83ab0458..1462d630e399c 100644 +--- a/drivers/power/supply/rt9467-charger.c ++++ b/drivers/power/supply/rt9467-charger.c +@@ -588,6 +588,10 @@ static int rt9467_run_aicl(struct rt9467_chg_data *data) + aicl_vth = mivr_vth + RT9467_AICLVTH_GAP_uV; + ret = rt9467_set_value_from_ranges(data, F_AICL_VTH, + RT9467_RANGE_AICL_VTH, aicl_vth); ++ if (ret) { ++ dev_err(data->dev, "Failed to set AICL VTH\n"); ++ return ret; ++ } + + /* Trigger AICL function */ + ret = regmap_field_write(data->rm_field[F_AICL_MEAS], 1); +-- +2.51.0 + diff --git a/queue-6.6/power-supply-wm831x-check-wm831x_set_bits-return-val.patch b/queue-6.6/power-supply-wm831x-check-wm831x_set_bits-return-val.patch new file mode 100644 index 0000000000..8139c48c4e --- /dev/null +++ b/queue-6.6/power-supply-wm831x-check-wm831x_set_bits-return-val.patch @@ -0,0 +1,54 @@ +From 3952e328c4333fc8c48f67355d3ac7afc938ba6f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 9 Oct 2025 20:05:52 +0300 +Subject: power: supply: wm831x: Check wm831x_set_bits() return value + +From: Ivan Abramov + +[ Upstream commit ea14bae6df18942bccb467fcf5ff33ca677b8253 ] + +Since wm831x_set_bits() may return error, log failure and exit from +wm831x_usb_limit_change() in such case. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 626b6cd5f52e ("power: wm831x_power: Support USB charger current limit management") +Signed-off-by: Ivan Abramov +Link: https://patch.msgid.link/20251009170553.566561-1-i.abramov@mt-integration.ru +Signed-off-by: Sebastian Reichel +Signed-off-by: Sasha Levin +--- + drivers/power/supply/wm831x_power.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/power/supply/wm831x_power.c b/drivers/power/supply/wm831x_power.c +index 82e31066c746e..bbae77982d086 100644 +--- a/drivers/power/supply/wm831x_power.c ++++ b/drivers/power/supply/wm831x_power.c +@@ -144,6 +144,7 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + struct wm831x_power, + usb_notify); + unsigned int i, best; ++ int ret; + + /* Find the highest supported limit */ + best = 0; +@@ -156,8 +157,13 @@ static int wm831x_usb_limit_change(struct notifier_block *nb, + dev_dbg(wm831x_power->wm831x->dev, + "Limiting USB current to %umA", wm831x_usb_limits[best]); + +- wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, +- WM831X_USB_ILIM_MASK, best); ++ ret = wm831x_set_bits(wm831x_power->wm831x, WM831X_POWER_STATE, ++ WM831X_USB_ILIM_MASK, best); ++ if (ret < 0) { ++ dev_err(wm831x_power->wm831x->dev, ++ "Failed to set USB current limit: %d\n", ret); ++ return ret; ++ } + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.6/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch b/queue-6.6/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch new file mode 100644 index 0000000000..1d01317608 --- /dev/null +++ b/queue-6.6/powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch @@ -0,0 +1,60 @@ +From a7937df51e7372dc151b1d9b4c288a7081635afc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Sep 2025 10:37:34 +0200 +Subject: powerpc/32: Fix unpaired stwcx. on interrupt exit + +From: Christophe Leroy + +[ Upstream commit 10e1c77c3636d815db802ceef588522c2d2d947c ] + +Commit b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C +exception exit from ppc64") erroneouly copied to powerpc/32 the logic +from powerpc/64 based on feature CPU_FTR_STCX_CHECKS_ADDRESS which is +always 0 on powerpc/32. + +Re-instate the logic implemented by commit b64f87c16f3c ("[POWERPC] +Avoid unpaired stwcx. on some processors") which is based on +CPU_FTR_NEED_PAIRED_STWCX feature. + +Fixes: b96bae3ae2cb ("powerpc/32: Replace ASM exception exit by C exception exit from ppc64") +Signed-off-by: Christophe Leroy +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/6040b5dbcf5cdaa1cd919fcf0790f12974ea6e5a.1757666244.git.christophe.leroy@csgroup.eu +Signed-off-by: Sasha Levin +--- + arch/powerpc/kernel/entry_32.S | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S +index 7eda33a24bb45..ba1670311bb04 100644 +--- a/arch/powerpc/kernel/entry_32.S ++++ b/arch/powerpc/kernel/entry_32.S +@@ -269,10 +269,9 @@ interrupt_return: + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_CCR(r1) + lwz r4,_LINK(r1) +@@ -315,10 +314,9 @@ ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + mtspr SPRN_SRR1,r12 + + BEGIN_FTR_SECTION ++ lwarx r0,0,r1 ++END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX) + stwcx. r0,0,r1 /* to clear the reservation */ +-FTR_SECTION_ELSE +- lwarx r0,0,r1 +-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS) + + lwz r3,_LINK(r1) + lwz r4,_CTR(r1) +-- +2.51.0 + diff --git a/queue-6.6/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch b/queue-6.6/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch new file mode 100644 index 0000000000..bfdf324bec --- /dev/null +++ b/queue-6.6/powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch @@ -0,0 +1,82 @@ +From e37aed8b5b4ec895d8e4fde5c40ba881e08fd7b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:27 +0530 +Subject: powerpc/64s/hash: Restrict stress_hpt_struct memblock region to + within RMA limit + +From: Ritesh Harjani (IBM) + +[ Upstream commit 17b45ccf09882e0c808ad2cf62acdc90ad968746 ] + +When HV=0 & IR/DR=0, the Hash MMU is said to be in Virtual Real +Addressing Mode during early boot. During this, we should ensure that +memory region allocations for stress_hpt_struct should happen from +within RMA region as otherwise the boot might get stuck while doing +memset of this region. + +History behind why do we have RMA region limitation is better explained +in these 2 patches [1] & [2]. This patch ensures that memset to +stress_hpt_struct during early boot does not cross ppc64_rma_size +boundary. + +[1]: https://lore.kernel.org/all/20190710052018.14628-1-sjitindarsingh@gmail.com/ +[2]: https://lore.kernel.org/all/87wp54usvj.fsf@linux.vnet.ibm.com/ + +Fixes: 6b34a099faa12 ("powerpc/64s/hash: add stress_hpt kernel boot option to increase hash faults") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/ada1173933ea7617a994d6ee3e54ced8797339fc.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/book3s64/hash_utils.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c +index ad2afa08e62ed..4f09d295e5188 100644 +--- a/arch/powerpc/mm/book3s64/hash_utils.c ++++ b/arch/powerpc/mm/book3s64/hash_utils.c +@@ -1032,11 +1032,14 @@ static void __init htab_initialize(void) + unsigned long table; + unsigned long pteg_count; + unsigned long prot; +- phys_addr_t base = 0, size = 0, end; ++ phys_addr_t base = 0, size = 0, end, limit = MEMBLOCK_ALLOC_ANYWHERE; + u64 i; + + DBG(" -> htab_initialize()\n"); + ++ if (firmware_has_feature(FW_FEATURE_LPAR)) ++ limit = ppc64_rma_size; ++ + if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) { + mmu_kernel_ssize = MMU_SEGSIZE_1T; + mmu_highuser_ssize = MMU_SEGSIZE_1T; +@@ -1052,7 +1055,7 @@ static void __init htab_initialize(void) + // Too early to use nr_cpu_ids, so use NR_CPUS + tmp = memblock_phys_alloc_range(sizeof(struct stress_hpt_struct) * NR_CPUS, + __alignof__(struct stress_hpt_struct), +- 0, MEMBLOCK_ALLOC_ANYWHERE); ++ MEMBLOCK_LOW_LIMIT, limit); + memset((void *)tmp, 0xff, sizeof(struct stress_hpt_struct) * NR_CPUS); + stress_hpt_struct = __va(tmp); + +@@ -1086,7 +1089,6 @@ static void __init htab_initialize(void) + mmu_hash_ops.hpte_clear_all(); + #endif + } else { +- unsigned long limit = MEMBLOCK_ALLOC_ANYWHERE; + + #ifdef CONFIG_PPC_CELL + /* +@@ -1102,7 +1104,7 @@ static void __init htab_initialize(void) + + table = memblock_phys_alloc_range(htab_size_bytes, + htab_size_bytes, +- 0, limit); ++ MEMBLOCK_LOW_LIMIT, limit); + if (!table) + panic("ERROR: Failed to allocate %pa bytes below %pa\n", + &htab_size_bytes, &limit); +-- +2.51.0 + diff --git a/queue-6.6/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch b/queue-6.6/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch new file mode 100644 index 0000000000..64459218e9 --- /dev/null +++ b/queue-6.6/powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch @@ -0,0 +1,53 @@ +From 56bec41c38a14f579dbd906109acf09776e4cb08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 20:27:28 +0530 +Subject: powerpc/64s/ptdump: Fix kernel_hash_pagetable dump for ISA v3.00 HPTE + format + +From: Ritesh Harjani (IBM) + +[ Upstream commit eae40a6da63faa9fb63ff61f8fa2b3b57da78a84 ] + +HPTE format was changed since Power9 (ISA 3.0) onwards. While dumping +kernel hash page tables, nothing gets printed on powernv P9+. This patch +utilizes the helpers added in the patch tagged as fixes, to convert new +format to old format and dump the hptes. This fix is only needed for +native_find() (powernv), since pseries continues to work fine with the +old format. + +Fixes: 6b243fcfb5f1e ("powerpc/64: Simplify adaptation to new ISA v3.00 HPTE format") +Signed-off-by: Ritesh Harjani (IBM) +Signed-off-by: Madhavan Srinivasan +Link: https://patch.msgid.link/4c2bb9e5b3cfbc0dd80b61b67cdd3ccfc632684c.1761834163.git.ritesh.list@gmail.com +Signed-off-by: Sasha Levin +--- + arch/powerpc/mm/ptdump/hashpagetable.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/powerpc/mm/ptdump/hashpagetable.c b/arch/powerpc/mm/ptdump/hashpagetable.c +index 9a601587836b2..ee5e1dfe7932a 100644 +--- a/arch/powerpc/mm/ptdump/hashpagetable.c ++++ b/arch/powerpc/mm/ptdump/hashpagetable.c +@@ -216,6 +216,8 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + vpn = hpt_vpn(ea, vsid, ssize); + hash = hpt_hash(vpn, shift, ssize); + want_v = hpte_encode_avpn(vpn, psize, ssize); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) ++ want_v = hpte_old_to_new_v(want_v); + + /* to check in the secondary hash table, we invert the hash */ + if (!primary) +@@ -229,6 +231,10 @@ static int native_find(unsigned long ea, int psize, bool primary, u64 *v, u64 + /* HPTE matches */ + *v = be64_to_cpu(hptep->v); + *r = be64_to_cpu(hptep->r); ++ if (cpu_has_feature(CPU_FTR_ARCH_300)) { ++ *v = hpte_new_to_old_v(*v, *r); ++ *r = hpte_new_to_old_r(*r); ++ } + return 0; + } + ++hpte_group; +-- +2.51.0 + diff --git a/queue-6.6/ps3disk-use-memcpy_-from-to-_bvec-index.patch b/queue-6.6/ps3disk-use-memcpy_-from-to-_bvec-index.patch new file mode 100644 index 0000000000..dee1972800 --- /dev/null +++ b/queue-6.6/ps3disk-use-memcpy_-from-to-_bvec-index.patch @@ -0,0 +1,48 @@ +From 400df4b4a456a3f7a31ff774f53f91c55792dca8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:30:33 +0100 +Subject: ps3disk: use memcpy_{from,to}_bvec index +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Rene Rebe + +[ Upstream commit 79bd8c9814a273fa7ba43399e1c07adec3fc95db ] + +With 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) converting +ps3disk to new bvec helpers, incrementing the offset was accidently +lost, corrupting consecutive buffers. Restore index for non-corrupted +data transfers. + +Fixes: 6e0a48552b8c (ps3disk: use memcpy_{from,to}_bvec) +Signed-off-by: René Rebe +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ps3disk.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c +index 36d7b36c60c76..79d3779e1c7ad 100644 +--- a/drivers/block/ps3disk.c ++++ b/drivers/block/ps3disk.c +@@ -85,10 +85,14 @@ static void ps3disk_scatter_gather(struct ps3_storage_device *dev, + struct bio_vec bvec; + + rq_for_each_segment(bvec, req, iter) { ++ dev_dbg(&dev->sbd.core, "%s:%u: %u sectors from %llu\n", ++ __func__, __LINE__, bio_sectors(iter.bio), ++ iter.bio->bi_iter.bi_sector); + if (gather) + memcpy_from_bvec(dev->bounce_buf + offset, &bvec); + else + memcpy_to_bvec(&bvec, dev->bounce_buf + offset); ++ offset += bvec.bv_len; + } + } + +-- +2.51.0 + diff --git a/queue-6.6/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch b/queue-6.6/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch new file mode 100644 index 0000000000..d668090a03 --- /dev/null +++ b/queue-6.6/pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch @@ -0,0 +1,87 @@ +From 33db6bbf143c58e0f66565cc56935a3297540bc2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 18 Nov 2025 18:43:02 +0100 +Subject: pwm: bcm2835: Make sure the channel is enabled after pwm_request() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit cda323dbda76600bf9761970d58517648f0de67d ] + +The .free callback cleared among others the enable bit PWENx in the +control register. When the PWM is requested later again this bit isn't +restored but the core assumes the PWM is enabled and thus skips a +request to configure the same state as before. + +To fix that don't touch the hardware configuration in .free(). For +symmetry also drop .request() and configure the mode completely in +.apply(). + +Fixes: e5a06dc5ac1f ("pwm: Add BCM2835 PWM driver") +Signed-off-by: Uwe Kleine-König +Reviewed-by: Florian Fainelli +Link: https://patch.msgid.link/20251118174303.1761577-2-u.kleine-koenig@baylibre.com +Signed-off-by: Uwe Kleine-König +Signed-off-by: Sasha Levin +--- + drivers/pwm/pwm-bcm2835.c | 28 +++------------------------- + 1 file changed, 3 insertions(+), 25 deletions(-) + +diff --git a/drivers/pwm/pwm-bcm2835.c b/drivers/pwm/pwm-bcm2835.c +index bdfc2a5ec0d69..5a51ba9b26d92 100644 +--- a/drivers/pwm/pwm-bcm2835.c ++++ b/drivers/pwm/pwm-bcm2835.c +@@ -35,29 +35,6 @@ static inline struct bcm2835_pwm *to_bcm2835_pwm(struct pwm_chip *chip) + return container_of(chip, struct bcm2835_pwm, chip); + } + +-static int bcm2835_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- value |= (PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +- +- return 0; +-} +- +-static void bcm2835_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) +-{ +- struct bcm2835_pwm *pc = to_bcm2835_pwm(chip); +- u32 value; +- +- value = readl(pc->base + PWM_CONTROL); +- value &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); +- writel(value, pc->base + PWM_CONTROL); +-} +- + static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + const struct pwm_state *state) + { +@@ -109,6 +86,9 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + /* set polarity */ + val = readl(pc->base + PWM_CONTROL); + ++ val &= ~(PWM_CONTROL_MASK << PWM_CONTROL_SHIFT(pwm->hwpwm)); ++ val |= PWM_MODE << PWM_CONTROL_SHIFT(pwm->hwpwm); ++ + if (state->polarity == PWM_POLARITY_NORMAL) + val &= ~(PWM_POLARITY << PWM_CONTROL_SHIFT(pwm->hwpwm)); + else +@@ -126,8 +106,6 @@ static int bcm2835_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, + } + + static const struct pwm_ops bcm2835_pwm_ops = { +- .request = bcm2835_pwm_request, +- .free = bcm2835_pwm_free, + .apply = bcm2835_pwm_apply, + .owner = THIS_MODULE, + }; +-- +2.51.0 + diff --git a/queue-6.6/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch b/queue-6.6/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch new file mode 100644 index 0000000000..4c7803e117 --- /dev/null +++ b/queue-6.6/rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch @@ -0,0 +1,111 @@ +From b46c293a28a5e8fc5f90b0be684121568e55badf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 10:02:34 +0800 +Subject: rculist: Add hlist_nulls_replace_rcu() and + hlist_nulls_replace_init_rcu() + +From: Xuanqiang Luo + +[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ] + +Add two functions to atomically replace RCU-protected hlist_nulls entries. + +Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as +mentioned in the patch below: +commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for +rculist_nulls") +commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for +hlist_nulls") + +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Frederic Weisbecker +Reviewed-by: Eric Dumazet +Signed-off-by: Xuanqiang Luo +Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev +Signed-off-by: Jakub Kicinski +Stable-dep-of: 1532ed0d0753 ("inet: Avoid ehash lookup race in inet_ehash_insert()") +Signed-off-by: Sasha Levin +--- + include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++ + 1 file changed, 59 insertions(+) + +diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h +index 89186c499dd47..c26cb83ca0711 100644 +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n) + #define hlist_nulls_next_rcu(node) \ + (*((struct hlist_nulls_node __rcu __force **)&(node)->next)) + ++/** ++ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node. ++ * @node: element of the list. ++ */ ++#define hlist_nulls_pprev_rcu(node) \ ++ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev)) ++ + /** + * hlist_nulls_del_rcu - deletes entry from hash list without re-initialization + * @n: the element to delete from the hash list. +@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n) + n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL); + } + ++/** ++ * hlist_nulls_replace_rcu - replace an old entry by a new one ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ struct hlist_nulls_node *next = old->next; ++ ++ WRITE_ONCE(new->next, next); ++ WRITE_ONCE(new->pprev, old->pprev); ++ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new); ++ if (!is_a_nulls(next)) ++ WRITE_ONCE(next->pprev, &new->next); ++} ++ ++/** ++ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and ++ * initialize the old ++ * @old: the element to be replaced ++ * @new: the new element to insert ++ * ++ * Description: ++ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while ++ * permitting racing traversals, and reinitialize the old entry. ++ * ++ * Note: @old must be hashed. ++ * ++ * The caller must take whatever precautions are necessary (such as holding ++ * appropriate locks) to avoid racing with another list-mutation primitive, such ++ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same ++ * list. However, it is perfectly legal to run concurrently with the _rcu ++ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu(). ++ */ ++static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old, ++ struct hlist_nulls_node *new) ++{ ++ hlist_nulls_replace_rcu(old, new); ++ WRITE_ONCE(old->pprev, NULL); ++} ++ + /** + * hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type + * @tpos: the type * to use as a loop cursor. +-- +2.51.0 + diff --git a/queue-6.6/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch b/queue-6.6/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch new file mode 100644 index 0000000000..e9ff19c14f --- /dev/null +++ b/queue-6.6/rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch @@ -0,0 +1,40 @@ +From 6b73f59b97afa689e0de360ae0121f5e3627d30e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 23:36:54 -0800 +Subject: RDMA/bnxt_re: Fix the inline size for GenP7 devices + +From: Selvin Xavier + +[ Upstream commit 6afe40ff484a1155b71158b911c65299496e35c3 ] + +Inline size supported by the device is based on the number +of SGEs supported by the adapter. Change the inline +size calculation based on that. + +Fixes: de1d364c3815 ("RDMA/bnxt_re: Add support for Variable WQE in Genp7 adapters") +Reviewed-by: Kashyap Desai +Signed-off-by: Kalesh AP +Signed-off-by: Selvin Xavier +Link: https://patch.msgid.link/1763624215-10382-1-git-send-email-selvin.xavier@broadcom.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/bnxt_re/qplib_sp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/hw/bnxt_re/qplib_sp.c b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +index 74c3f6b26c4d3..0b713c1821c3b 100644 +--- a/drivers/infiniband/hw/bnxt_re/qplib_sp.c ++++ b/drivers/infiniband/hw/bnxt_re/qplib_sp.c +@@ -161,7 +161,7 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, + attr->max_srq_wqes = le32_to_cpu(sb->max_srq_wr) - 1; + attr->max_srq_sges = sb->max_srq_sge; + attr->max_pkey = 1; +- attr->max_inline_data = le32_to_cpu(sb->max_inline_data); ++ attr->max_inline_data = attr->max_qp_sges * sizeof(struct sq_sge); + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) + attr->l2_db_size = (sb->l2_db_space_size + 1) * + (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); +-- +2.51.0 + diff --git a/queue-6.6/rdma-irdma-add-support-to-re-register-a-memory-regio.patch b/queue-6.6/rdma-irdma-add-support-to-re-register-a-memory-regio.patch new file mode 100644 index 0000000000..a802f5b45d --- /dev/null +++ b/queue-6.6/rdma-irdma-add-support-to-re-register-a-memory-regio.patch @@ -0,0 +1,362 @@ +From d71077883a00222ce6251f89799a02b5bef5242f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 4 Oct 2023 10:13:06 -0500 +Subject: RDMA/irdma: Add support to re-register a memory region + +From: Sindhu Devale + +[ Upstream commit 5ac388db27c443dadfbb0b8b23fa7ccf429d901a ] + +Add support for reregister MR verb API by doing a de-register +followed by a register MR with the new attributes. Reuse resources +like iwmr handle and HW stag where possible. + +Signed-off-by: Sindhu Devale +Signed-off-by: Shiraz Saleem +Link: https://lore.kernel.org/r/20231004151306.228-1-shiraz.saleem@intel.com +Signed-off-by: Leon Romanovsky +Stable-dep-of: 71d3bdae5eab ("RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY") +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/verbs.c | 232 ++++++++++++++++++++++------ + drivers/infiniband/hw/irdma/verbs.h | 2 + + 2 files changed, 191 insertions(+), 43 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index 29540b2b2373c..aece20f105918 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2661,8 +2661,11 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + cqp_info->in.u.alloc_stag.scratch = (uintptr_t)cqp_request; + status = irdma_handle_cqp_op(iwdev->rf, cqp_request); + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); ++ if (status) ++ return status; + +- return status; ++ iwmr->is_hwreg = 1; ++ return 0; + } + + /** +@@ -2828,14 +2831,18 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + ret = irdma_handle_cqp_op(iwdev->rf, cqp_request); + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + ++ if (!ret) ++ iwmr->is_hwreg = 1; ++ + return ret; + } + +-static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) ++static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access, ++ bool create_stag) + { + struct irdma_device *iwdev = to_iwdev(iwmr->ibmr.device); + struct irdma_pbl *iwpbl = &iwmr->iwpbl; +- u32 stag; ++ u32 stag = 0; + u8 lvl; + int err; + +@@ -2854,15 +2861,18 @@ static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) + } + } + +- stag = irdma_create_stag(iwdev); +- if (!stag) { +- err = -ENOMEM; +- goto free_pble; ++ if (create_stag) { ++ stag = irdma_create_stag(iwdev); ++ if (!stag) { ++ err = -ENOMEM; ++ goto free_pble; ++ } ++ ++ iwmr->stag = stag; ++ iwmr->ibmr.rkey = stag; ++ iwmr->ibmr.lkey = stag; + } + +- iwmr->stag = stag; +- iwmr->ibmr.rkey = stag; +- iwmr->ibmr.lkey = stag; + err = irdma_hwreg_mr(iwdev, iwmr, access); + if (err) + goto err_hwreg; +@@ -2870,7 +2880,8 @@ static int irdma_reg_user_mr_type_mem(struct irdma_mr *iwmr, int access) + return 0; + + err_hwreg: +- irdma_free_stag(iwdev, stag); ++ if (stag) ++ irdma_free_stag(iwdev, stag); + + free_pble: + if (iwpbl->pble_alloc.level != PBLE_LEVEL_0 && iwpbl->pbl_allocated) +@@ -3050,7 +3061,7 @@ static struct ib_mr *irdma_reg_user_mr(struct ib_pd *pd, u64 start, u64 len, + goto error; + break; + case IRDMA_MEMREG_TYPE_MEM: +- err = irdma_reg_user_mr_type_mem(iwmr, access); ++ err = irdma_reg_user_mr_type_mem(iwmr, access, true); + if (err) + goto error; + +@@ -3094,7 +3105,7 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start, + goto err_release; + } + +- err = irdma_reg_user_mr_type_mem(iwmr, access); ++ err = irdma_reg_user_mr_type_mem(iwmr, access, true); + if (err) + goto err_iwmr; + +@@ -3109,6 +3120,161 @@ static struct ib_mr *irdma_reg_user_mr_dmabuf(struct ib_pd *pd, u64 start, + return ERR_PTR(err); + } + ++static int irdma_hwdereg_mr(struct ib_mr *ib_mr) ++{ ++ struct irdma_device *iwdev = to_iwdev(ib_mr->device); ++ struct irdma_mr *iwmr = to_iwmr(ib_mr); ++ struct irdma_pd *iwpd = to_iwpd(ib_mr->pd); ++ struct irdma_dealloc_stag_info *info; ++ struct irdma_pbl *iwpbl = &iwmr->iwpbl; ++ struct irdma_cqp_request *cqp_request; ++ struct cqp_cmds_info *cqp_info; ++ int status; ++ ++ /* Skip HW MR de-register when it is already de-registered ++ * during an MR re-reregister and the re-registration fails ++ */ ++ if (!iwmr->is_hwreg) ++ return 0; ++ ++ cqp_request = irdma_alloc_and_get_cqp_request(&iwdev->rf->cqp, true); ++ if (!cqp_request) ++ return -ENOMEM; ++ ++ cqp_info = &cqp_request->info; ++ info = &cqp_info->in.u.dealloc_stag.info; ++ memset(info, 0, sizeof(*info)); ++ info->pd_id = iwpd->sc_pd.pd_id; ++ info->stag_idx = ib_mr->rkey >> IRDMA_CQPSQ_STAG_IDX_S; ++ info->mr = true; ++ if (iwpbl->pbl_allocated) ++ info->dealloc_pbl = true; ++ ++ cqp_info->cqp_cmd = IRDMA_OP_DEALLOC_STAG; ++ cqp_info->post_sq = 1; ++ cqp_info->in.u.dealloc_stag.dev = &iwdev->rf->sc_dev; ++ cqp_info->in.u.dealloc_stag.scratch = (uintptr_t)cqp_request; ++ status = irdma_handle_cqp_op(iwdev->rf, cqp_request); ++ irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); ++ if (status) ++ return status; ++ ++ iwmr->is_hwreg = 0; ++ return 0; ++} ++ ++/* ++ * irdma_rereg_mr_trans - Re-register a user MR for a change translation. ++ * @iwmr: ptr of iwmr ++ * @start: virtual start address ++ * @len: length of mr ++ * @virt: virtual address ++ * ++ * Re-register a user memory region when a change translation is requested. ++ * Re-register a new region while reusing the stag from the original registration. ++ */ ++static int irdma_rereg_mr_trans(struct irdma_mr *iwmr, u64 start, u64 len, ++ u64 virt) ++{ ++ struct irdma_device *iwdev = to_iwdev(iwmr->ibmr.device); ++ struct irdma_pbl *iwpbl = &iwmr->iwpbl; ++ struct ib_pd *pd = iwmr->ibmr.pd; ++ struct ib_umem *region; ++ int err; ++ ++ region = ib_umem_get(pd->device, start, len, iwmr->access); ++ if (IS_ERR(region)) ++ return PTR_ERR(region); ++ ++ iwmr->region = region; ++ iwmr->ibmr.iova = virt; ++ iwmr->ibmr.pd = pd; ++ iwmr->page_size = ib_umem_find_best_pgsz(region, ++ iwdev->rf->sc_dev.hw_attrs.page_size_cap, ++ virt); ++ if (unlikely(!iwmr->page_size)) { ++ err = -EOPNOTSUPP; ++ goto err; ++ } ++ ++ iwmr->len = region->length; ++ iwpbl->user_base = virt; ++ iwmr->page_cnt = ib_umem_num_dma_blocks(region, iwmr->page_size); ++ ++ err = irdma_reg_user_mr_type_mem(iwmr, iwmr->access, false); ++ if (err) ++ goto err; ++ ++ return 0; ++ ++err: ++ ib_umem_release(region); ++ return err; ++} ++ ++/* ++ * irdma_rereg_user_mr - Re-Register a user memory region(MR) ++ * @ibmr: ib mem to access iwarp mr pointer ++ * @flags: bit mask to indicate which of the attr's of MR modified ++ * @start: virtual start address ++ * @len: length of mr ++ * @virt: virtual address ++ * @new_access: bit mask of access flags ++ * @new_pd: ptr of pd ++ * @udata: user data ++ * ++ * Return: ++ * NULL - Success, existing MR updated ++ * ERR_PTR - error occurred ++ */ ++static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, ++ u64 start, u64 len, u64 virt, ++ int new_access, struct ib_pd *new_pd, ++ struct ib_udata *udata) ++{ ++ struct irdma_device *iwdev = to_iwdev(ib_mr->device); ++ struct irdma_mr *iwmr = to_iwmr(ib_mr); ++ struct irdma_pbl *iwpbl = &iwmr->iwpbl; ++ int ret; ++ ++ if (len > iwdev->rf->sc_dev.hw_attrs.max_mr_size) ++ return ERR_PTR(-EINVAL); ++ ++ if (flags & ~(IB_MR_REREG_TRANS | IB_MR_REREG_PD | IB_MR_REREG_ACCESS)) ++ return ERR_PTR(-EOPNOTSUPP); ++ ++ ret = irdma_hwdereg_mr(ib_mr); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ if (flags & IB_MR_REREG_ACCESS) ++ iwmr->access = new_access; ++ ++ if (flags & IB_MR_REREG_PD) { ++ iwmr->ibmr.pd = new_pd; ++ iwmr->ibmr.device = new_pd->device; ++ } ++ ++ if (flags & IB_MR_REREG_TRANS) { ++ if (iwpbl->pbl_allocated) { ++ irdma_free_pble(iwdev->rf->pble_rsrc, ++ &iwpbl->pble_alloc); ++ iwpbl->pbl_allocated = false; ++ } ++ if (iwmr->region) { ++ ib_umem_release(iwmr->region); ++ iwmr->region = NULL; ++ } ++ ++ ret = irdma_rereg_mr_trans(iwmr, start, len, virt); ++ } else ++ ret = irdma_hwreg_mr(iwdev, iwmr, iwmr->access); ++ if (ret) ++ return ERR_PTR(ret); ++ ++ return NULL; ++} ++ + /** + * irdma_reg_phys_mr - register kernel physical memory + * @pd: ibpd pointer +@@ -3216,16 +3382,10 @@ static void irdma_del_memlist(struct irdma_mr *iwmr, + */ + static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) + { +- struct ib_pd *ibpd = ib_mr->pd; +- struct irdma_pd *iwpd = to_iwpd(ibpd); + struct irdma_mr *iwmr = to_iwmr(ib_mr); + struct irdma_device *iwdev = to_iwdev(ib_mr->device); +- struct irdma_dealloc_stag_info *info; + struct irdma_pbl *iwpbl = &iwmr->iwpbl; +- struct irdma_pble_alloc *palloc = &iwpbl->pble_alloc; +- struct irdma_cqp_request *cqp_request; +- struct cqp_cmds_info *cqp_info; +- int status; ++ int ret; + + if (iwmr->type != IRDMA_MEMREG_TYPE_MEM) { + if (iwmr->region) { +@@ -3239,33 +3399,18 @@ static int irdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata) + goto done; + } + +- cqp_request = irdma_alloc_and_get_cqp_request(&iwdev->rf->cqp, true); +- if (!cqp_request) +- return -ENOMEM; +- +- cqp_info = &cqp_request->info; +- info = &cqp_info->in.u.dealloc_stag.info; +- memset(info, 0, sizeof(*info)); +- info->pd_id = iwpd->sc_pd.pd_id; +- info->stag_idx = ib_mr->rkey >> IRDMA_CQPSQ_STAG_IDX_S; +- info->mr = true; +- if (iwpbl->pbl_allocated) +- info->dealloc_pbl = true; +- +- cqp_info->cqp_cmd = IRDMA_OP_DEALLOC_STAG; +- cqp_info->post_sq = 1; +- cqp_info->in.u.dealloc_stag.dev = &iwdev->rf->sc_dev; +- cqp_info->in.u.dealloc_stag.scratch = (uintptr_t)cqp_request; +- status = irdma_handle_cqp_op(iwdev->rf, cqp_request); +- irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); +- if (status) +- return status; ++ ret = irdma_hwdereg_mr(ib_mr); ++ if (ret) ++ return ret; + + irdma_free_stag(iwdev, iwmr->stag); + done: + if (iwpbl->pbl_allocated) +- irdma_free_pble(iwdev->rf->pble_rsrc, palloc); +- ib_umem_release(iwmr->region); ++ irdma_free_pble(iwdev->rf->pble_rsrc, &iwpbl->pble_alloc); ++ ++ if (iwmr->region) ++ ib_umem_release(iwmr->region); ++ + kfree(iwmr); + + return 0; +@@ -4595,6 +4740,7 @@ static const struct ib_device_ops irdma_dev_ops = { + .query_qp = irdma_query_qp, + .reg_user_mr = irdma_reg_user_mr, + .reg_user_mr_dmabuf = irdma_reg_user_mr_dmabuf, ++ .rereg_user_mr = irdma_rereg_user_mr, + .req_notify_cq = irdma_req_notify_cq, + .resize_cq = irdma_resize_cq, + INIT_RDMA_OBJ_SIZE(ib_pd, irdma_pd, ibpd), +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index bb9ab945938e0..533b4597c407f 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -100,6 +100,8 @@ struct irdma_mr { + struct ib_mw ibmw; + }; + struct ib_umem *region; ++ int access; ++ u8 is_hwreg; + u16 type; + u32 page_cnt; + u64 page_size; +-- +2.51.0 + diff --git a/queue-6.6/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch b/queue-6.6/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch new file mode 100644 index 0000000000..782f01ac1c --- /dev/null +++ b/queue-6.6/rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch @@ -0,0 +1,166 @@ +From a017f6fd01881020df77ac161d5f86e5ac7dc425 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:47 -0600 +Subject: RDMA/irdma: Do not directly rely on IB_PD_UNSAFE_GLOBAL_RKEY + +From: Jacob Moroni + +[ Upstream commit 71d3bdae5eab21cf8991a6f3cd914caa31d5a51f ] + +The HW disables bounds checking for MRs with a length of zero, so +the driver will only allow a zero length MR if the "all_memory" +flag is set, and this flag is only set if IB_PD_UNSAFE_GLOBAL_RKEY +is set for the PD. + +This means that the "get_dma_mr" method will currently fail unless +the IB_PD_UNSAFE_GLOBAL_RKEY flag is set. This has not been an issue +because the "get_dma_mr" method is only ever invoked if the device +does not support the local DMA key or if IB_PD_UNSAFE_GLOBAL_RKEY +is set, and so far, all IRDMA HW supports the local DMA lkey. + +However, some new HW does not support the local DMA lkey, so the +"get_dma_mr" method needs to work without IB_PD_UNSAFE_GLOBAL_RKEY +being set. + +To support HW that does not allow the local DMA lkey, the logic has +been changed to pass an explicit flag to indicate when a dma_mr is +being created so that the zero length will be allowed. + +Also, the "all_memory" flag has been forced to false for normal MR +allocation since these MRs are never supposed to provide global +unsafe rkey semantics anyway; only the MR created with "get_dma_mr" +should support this. + +Fixes: bb6d73d9add6 ("RDMA/irdma: Prevent zero-length STAG registration") +Signed-off-by: Jacob Moroni +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-7-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/cm.c | 2 +- + drivers/infiniband/hw/irdma/main.h | 2 +- + drivers/infiniband/hw/irdma/verbs.c | 15 ++++++++------- + drivers/infiniband/hw/irdma/verbs.h | 3 ++- + 4 files changed, 12 insertions(+), 10 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/cm.c b/drivers/infiniband/hw/irdma/cm.c +index 1916daa8c3323..b3f14816251b4 100644 +--- a/drivers/infiniband/hw/irdma/cm.c ++++ b/drivers/infiniband/hw/irdma/cm.c +@@ -3708,7 +3708,7 @@ int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) + iwpd = iwqp->iwpd; + tagged_offset = (uintptr_t)iwqp->ietf_mem.va; + ibmr = irdma_reg_phys_mr(&iwpd->ibpd, iwqp->ietf_mem.pa, buf_len, +- IB_ACCESS_LOCAL_WRITE, &tagged_offset); ++ IB_ACCESS_LOCAL_WRITE, &tagged_offset, false); + if (IS_ERR(ibmr)) { + ret = -ENOMEM; + goto error; +diff --git a/drivers/infiniband/hw/irdma/main.h b/drivers/infiniband/hw/irdma/main.h +index cbf0db72e1088..28963e19d9555 100644 +--- a/drivers/infiniband/hw/irdma/main.h ++++ b/drivers/infiniband/hw/irdma/main.h +@@ -535,7 +535,7 @@ void irdma_copy_ip_htonl(__be32 *dst, u32 *src); + u16 irdma_get_vlan_ipv4(u32 *addr); + void irdma_get_vlan_mac_ipv6(u32 *addr, u16 *vlan_id, u8 *mac); + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *ib_pd, u64 addr, u64 size, +- int acc, u64 *iova_start); ++ int acc, u64 *iova_start, bool dma_mr); + int irdma_upload_qp_context(struct irdma_qp *iwqp, bool freeze, bool raw); + void irdma_cqp_ce_handler(struct irdma_pci_f *rf, struct irdma_sc_cq *cq); + int irdma_ah_cqp_op(struct irdma_pci_f *rf, struct irdma_sc_ah *sc_ah, u8 cmd, +diff --git a/drivers/infiniband/hw/irdma/verbs.c b/drivers/infiniband/hw/irdma/verbs.c +index aece20f105918..b52e0716d23fc 100644 +--- a/drivers/infiniband/hw/irdma/verbs.c ++++ b/drivers/infiniband/hw/irdma/verbs.c +@@ -2653,7 +2653,6 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + info->stag_idx = iwmr->stag >> IRDMA_CQPSQ_STAG_IDX_S; + info->pd_id = iwpd->sc_pd.pd_id; + info->total_len = iwmr->len; +- info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; + info->remote_access = true; + cqp_info->cqp_cmd = IRDMA_OP_ALLOC_STAG; + cqp_info->post_sq = 1; +@@ -2664,7 +2663,7 @@ static int irdma_hw_alloc_stag(struct irdma_device *iwdev, + if (status) + return status; + +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + return 0; + } + +@@ -2805,7 +2804,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + stag_info->total_len = iwmr->len; + stag_info->access_rights = irdma_get_mr_access(access); + stag_info->pd_id = iwpd->sc_pd.pd_id; +- stag_info->all_memory = pd->flags & IB_PD_UNSAFE_GLOBAL_RKEY; ++ stag_info->all_memory = iwmr->dma_mr; + if (stag_info->access_rights & IRDMA_ACCESS_FLAGS_ZERO_BASED) + stag_info->addr_type = IRDMA_ADDR_TYPE_ZERO_BASED; + else +@@ -2832,7 +2831,7 @@ static int irdma_hwreg_mr(struct irdma_device *iwdev, struct irdma_mr *iwmr, + irdma_put_cqp_request(&iwdev->rf->cqp, cqp_request); + + if (!ret) +- iwmr->is_hwreg = 1; ++ iwmr->is_hwreg = true; + + return ret; + } +@@ -3159,7 +3158,7 @@ static int irdma_hwdereg_mr(struct ib_mr *ib_mr) + if (status) + return status; + +- iwmr->is_hwreg = 0; ++ iwmr->is_hwreg = false; + return 0; + } + +@@ -3282,9 +3281,10 @@ static struct ib_mr *irdma_rereg_user_mr(struct ib_mr *ib_mr, int flags, + * @size: size of memory to register + * @access: Access rights + * @iova_start: start of virtual address for physical buffers ++ * @dma_mr: Flag indicating whether this region is a PD DMA MR + */ + struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access, +- u64 *iova_start) ++ u64 *iova_start, bool dma_mr) + { + struct irdma_device *iwdev = to_iwdev(pd->device); + struct irdma_pbl *iwpbl; +@@ -3301,6 +3301,7 @@ struct ib_mr *irdma_reg_phys_mr(struct ib_pd *pd, u64 addr, u64 size, int access + iwpbl = &iwmr->iwpbl; + iwpbl->iwmr = iwmr; + iwmr->type = IRDMA_MEMREG_TYPE_MEM; ++ iwmr->dma_mr = dma_mr; + iwpbl->user_base = *iova_start; + stag = irdma_create_stag(iwdev); + if (!stag) { +@@ -3339,7 +3340,7 @@ static struct ib_mr *irdma_get_dma_mr(struct ib_pd *pd, int acc) + { + u64 kva = 0; + +- return irdma_reg_phys_mr(pd, 0, 0, acc, &kva); ++ return irdma_reg_phys_mr(pd, 0, 0, acc, &kva, true); + } + + /** +diff --git a/drivers/infiniband/hw/irdma/verbs.h b/drivers/infiniband/hw/irdma/verbs.h +index 533b4597c407f..97abd45a5cee2 100644 +--- a/drivers/infiniband/hw/irdma/verbs.h ++++ b/drivers/infiniband/hw/irdma/verbs.h +@@ -101,7 +101,8 @@ struct irdma_mr { + }; + struct ib_umem *region; + int access; +- u8 is_hwreg; ++ bool is_hwreg:1; ++ bool dma_mr:1; + u16 type; + u32 page_cnt; + u64 page_size; +-- +2.51.0 + diff --git a/queue-6.6/rdma-irdma-fix-data-race-in-irdma_free_pble.patch b/queue-6.6/rdma-irdma-fix-data-race-in-irdma_free_pble.patch new file mode 100644 index 0000000000..8b8d3bec5b --- /dev/null +++ b/queue-6.6/rdma-irdma-fix-data-race-in-irdma_free_pble.patch @@ -0,0 +1,80 @@ +From c5025317a60eaee9dbc451c11e0bba075abc4ed8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:43 -0600 +Subject: RDMA/irdma: Fix data race in irdma_free_pble + +From: Krzysztof Czurylo + +[ Upstream commit 81f44409fb4f027d1e6d54edbeba5156ad94b214 ] + +Protects pble_rsrc counters with mutex to prevent data race. +Fixes the following data race in irdma_free_pble reported by KCSAN: + +BUG: KCSAN: data-race in irdma_free_pble [irdma] / irdma_free_pble [irdma] + +write to 0xffff91430baa0078 of 8 bytes by task 16956 on cpu 5: + irdma_free_pble+0x3b/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +read to 0xffff91430baa0078 of 8 bytes by task 16953 on cpu 2: + irdma_free_pble+0x23/0xb0 [irdma] + irdma_dereg_mr+0x108/0x110 [irdma] + ib_dereg_mr_user+0x74/0x160 [ib_core] + uverbs_free_mr+0x26/0x30 [ib_uverbs] + destroy_hw_idr_uobject+0x4a/0x90 [ib_uverbs] + uverbs_destroy_uobject+0x7b/0x330 [ib_uverbs] + uobj_destroy+0x61/0xb0 [ib_uverbs] + ib_uverbs_run_method+0x1f2/0x380 [ib_uverbs] + ib_uverbs_cmd_verbs+0x365/0x440 [ib_uverbs] + ib_uverbs_ioctl+0x111/0x190 [ib_uverbs] + __x64_sys_ioctl+0xc9/0x100 + do_syscall_64+0x44/0xa0 + entry_SYSCALL_64_after_hwframe+0x6e/0xd8 + +value changed: 0x0000000000005a62 -> 0x0000000000005a68 + +Fixes: e8c4dbc2fcac ("RDMA/irdma: Add PBLE resource manager") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-3-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/pble.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/infiniband/hw/irdma/pble.c b/drivers/infiniband/hw/irdma/pble.c +index fa096557adc83..c7bcdc1bf9319 100644 +--- a/drivers/infiniband/hw/irdma/pble.c ++++ b/drivers/infiniband/hw/irdma/pble.c +@@ -498,12 +498,14 @@ int irdma_get_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + void irdma_free_pble(struct irdma_hmc_pble_rsrc *pble_rsrc, + struct irdma_pble_alloc *palloc) + { +- pble_rsrc->freedpbles += palloc->total_cnt; +- + if (palloc->level == PBLE_LEVEL_2) + free_lvl2(pble_rsrc, palloc); + else + irdma_prm_return_pbles(&pble_rsrc->pinfo, + &palloc->level1.chunkinfo); ++ ++ mutex_lock(&pble_rsrc->pble_mutex_lock); ++ pble_rsrc->freedpbles += palloc->total_cnt; + pble_rsrc->stats_alloc_freed++; ++ mutex_unlock(&pble_rsrc->pble_mutex_lock); + } +-- +2.51.0 + diff --git a/queue-6.6/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch b/queue-6.6/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch new file mode 100644 index 0000000000..be3c7a2b1b --- /dev/null +++ b/queue-6.6/rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch @@ -0,0 +1,78 @@ +From 9d508ea89858ac19682c485cbaa0f4ad13fd061b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 20:53:42 -0600 +Subject: RDMA/irdma: Fix data race in irdma_sc_ccq_arm + +From: Krzysztof Czurylo + +[ Upstream commit a521928164433de44fed5aaf5f49aeb3f1fb96f5 ] + +Adds a lock around irdma_sc_ccq_arm body to prevent inter-thread data race. +Fixes data race in irdma_sc_ccq_arm() reported by KCSAN: + +BUG: KCSAN: data-race in irdma_sc_ccq_arm [irdma] / irdma_sc_ccq_arm [irdma] + +read to 0xffff9d51b4034220 of 8 bytes by task 255 on cpu 11: + irdma_sc_ccq_arm+0x36/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + cqp_compl_worker+0x2a/0x40 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +write to 0xffff9d51b4034220 of 8 bytes by task 89 on cpu 3: + irdma_sc_ccq_arm+0x7e/0xd0 [irdma] + irdma_cqp_ce_handler+0x300/0x310 [irdma] + irdma_wait_event+0xd4/0x3e0 [irdma] + irdma_handle_cqp_op+0xa5/0x220 [irdma] + irdma_hw_flush_wqes+0xb1/0x300 [irdma] + irdma_flush_wqes+0x22e/0x3a0 [irdma] + irdma_cm_disconn_true+0x4c7/0x5d0 [irdma] + irdma_disconnect_worker+0x35/0x50 [irdma] + process_one_work+0x402/0x7e0 + worker_thread+0xb3/0x6d0 + kthread+0x178/0x1a0 + ret_from_fork+0x2c/0x50 + +value changed: 0x0000000000024000 -> 0x0000000000034000 + +Fixes: 3f49d6842569 ("RDMA/irdma: Implement HW Admin Queue OPs") +Signed-off-by: Krzysztof Czurylo +Signed-off-by: Tatyana Nikolova +Link: https://patch.msgid.link/20251125025350.180-2-tatyana.e.nikolova@intel.com +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/hw/irdma/ctrl.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/infiniband/hw/irdma/ctrl.c b/drivers/infiniband/hw/irdma/ctrl.c +index 8a6200e55c542..ebbece4f09a22 100644 +--- a/drivers/infiniband/hw/irdma/ctrl.c ++++ b/drivers/infiniband/hw/irdma/ctrl.c +@@ -3316,11 +3316,13 @@ int irdma_sc_cqp_destroy(struct irdma_sc_cqp *cqp) + */ + void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + { ++ unsigned long flags; + u64 temp_val; + u16 sw_cq_sel; + u8 arm_next_se; + u8 arm_seq_num; + ++ spin_lock_irqsave(&ccq->dev->cqp_lock, flags); + get_64bit_val(ccq->cq_uk.shadow_area, 32, &temp_val); + sw_cq_sel = (u16)FIELD_GET(IRDMA_CQ_DBSA_SW_CQ_SELECT, temp_val); + arm_next_se = (u8)FIELD_GET(IRDMA_CQ_DBSA_ARM_NEXT_SE, temp_val); +@@ -3331,6 +3333,7 @@ void irdma_sc_ccq_arm(struct irdma_sc_cq *ccq) + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT_SE, arm_next_se) | + FIELD_PREP(IRDMA_CQ_DBSA_ARM_NEXT, 1); + set_64bit_val(ccq->cq_uk.shadow_area, 32, temp_val); ++ spin_unlock_irqrestore(&ccq->dev->cqp_lock, flags); + + dma_wmb(); /* make sure shadow area is updated before arming */ + +-- +2.51.0 + diff --git a/queue-6.6/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch b/queue-6.6/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch new file mode 100644 index 0000000000..de4a0be4dc --- /dev/null +++ b/queue-6.6/rdma-rtrs-server-fix-error-handling-in-get_or_create.patch @@ -0,0 +1,41 @@ +From 55d170b2b3d9a483a0b651ed79309600f8253083 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 08:51:58 +0800 +Subject: RDMA/rtrs: server: Fix error handling in get_or_create_srv + +From: Ma Ke + +[ Upstream commit a338d6e849ab31f32c08b4fcac11c0c72afbb150 ] + +After device_initialize() is called, use put_device() to release the +device according to kernel device management rules. While direct +kfree() work in this case, using put_device() is more correct. + +Found by code review. + +Fixes: 9cb837480424 ("RDMA/rtrs: server: main functionality") +Signed-off-by: Ma Ke +Link: https://patch.msgid.link/20251110005158.13394-1-make24@iscas.ac.cn +Acked-by: Jack Wang +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/ulp/rtrs/rtrs-srv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/infiniband/ulp/rtrs/rtrs-srv.c b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +index 84d1654148d76..5dbf315630c1a 100644 +--- a/drivers/infiniband/ulp/rtrs/rtrs-srv.c ++++ b/drivers/infiniband/ulp/rtrs/rtrs-srv.c +@@ -1443,7 +1443,7 @@ static struct rtrs_srv_sess *get_or_create_srv(struct rtrs_srv_ctx *ctx, + kfree(srv->chunks); + + err_free_srv: +- kfree(srv); ++ put_device(&srv->dev); + return ERR_PTR(-ENOMEM); + } + +-- +2.51.0 + diff --git a/queue-6.6/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch b/queue-6.6/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch new file mode 100644 index 0000000000..d04d9fddda --- /dev/null +++ b/queue-6.6/rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch @@ -0,0 +1,94 @@ +From e5ec6a5e80756256eb5c28420b74e2a1e8351e11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:52:03 -0700 +Subject: RDMA/rxe: Fix null deref on srq->rq.queue after resize failure + +From: Zhu Yanjun + +[ Upstream commit 503a5e4690ae14c18570141bc0dcf7501a8419b0 ] + +A NULL pointer dereference can occur in rxe_srq_chk_attr() when +ibv_modify_srq() is invoked twice in succession under certain error +conditions. The first call may fail in rxe_queue_resize(), which leads +rxe_srq_from_attr() to set srq->rq.queue = NULL. The second call then +triggers a crash (null deref) when accessing +srq->rq.queue->buf->index_mask. + +Call Trace: + +rxe_modify_srq+0x170/0x480 [rdma_rxe] +? __pfx_rxe_modify_srq+0x10/0x10 [rdma_rxe] +? uverbs_try_lock_object+0x4f/0xa0 [ib_uverbs] +? rdma_lookup_get_uobject+0x1f0/0x380 [ib_uverbs] +ib_uverbs_modify_srq+0x204/0x290 [ib_uverbs] +? __pfx_ib_uverbs_modify_srq+0x10/0x10 [ib_uverbs] +? tryinc_node_nr_active+0xe6/0x150 +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x2c0/0x470 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +? uverbs_fill_udata+0xed/0x4f0 [ib_uverbs] +ib_uverbs_run_method+0x55a/0x6e0 [ib_uverbs] +? __pfx_ib_uverbs_handler_UVERBS_METHOD_INVOKE_WRITE+0x10/0x10 [ib_uverbs] +ib_uverbs_cmd_verbs+0x54d/0x800 [ib_uverbs] +? __pfx_ib_uverbs_cmd_verbs+0x10/0x10 [ib_uverbs] +? __pfx___raw_spin_lock_irqsave+0x10/0x10 +? __pfx_do_vfs_ioctl+0x10/0x10 +? ioctl_has_perm.constprop.0.isra.0+0x2c7/0x4c0 +? __pfx_ioctl_has_perm.constprop.0.isra.0+0x10/0x10 +ib_uverbs_ioctl+0x13e/0x220 [ib_uverbs] +? __pfx_ib_uverbs_ioctl+0x10/0x10 [ib_uverbs] +__x64_sys_ioctl+0x138/0x1c0 +do_syscall_64+0x82/0x250 +? fdget_pos+0x58/0x4c0 +? ksys_write+0xf3/0x1c0 +? __pfx_ksys_write+0x10/0x10 +? do_syscall_64+0xc8/0x250 +? __pfx_vm_mmap_pgoff+0x10/0x10 +? fget+0x173/0x230 +? fput+0x2a/0x80 +? ksys_mmap_pgoff+0x224/0x4c0 +? do_syscall_64+0xc8/0x250 +? do_user_addr_fault+0x37b/0xfe0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +? clear_bhb_loop+0x50/0xa0 +entry_SYSCALL_64_after_hwframe+0x76/0x7e + +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Tested-by: Liu Yi +Signed-off-by: Zhu Yanjun +Link: https://patch.msgid.link/20251027215203.1321-1-yanjun.zhu@linux.dev +Signed-off-by: Leon Romanovsky +Signed-off-by: Sasha Levin +--- + drivers/infiniband/sw/rxe/rxe_srq.c | 7 +------ + 1 file changed, 1 insertion(+), 6 deletions(-) + +diff --git a/drivers/infiniband/sw/rxe/rxe_srq.c b/drivers/infiniband/sw/rxe/rxe_srq.c +index 3661cb627d28a..2a234f26ac104 100644 +--- a/drivers/infiniband/sw/rxe/rxe_srq.c ++++ b/drivers/infiniband/sw/rxe/rxe_srq.c +@@ -171,7 +171,7 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + udata, mi, &srq->rq.producer_lock, + &srq->rq.consumer_lock); + if (err) +- goto err_free; ++ return err; + + srq->rq.max_wr = attr->max_wr; + } +@@ -180,11 +180,6 @@ int rxe_srq_from_attr(struct rxe_dev *rxe, struct rxe_srq *srq, + srq->limit = attr->srq_limit; + + return 0; +- +-err_free: +- rxe_queue_cleanup(q); +- srq->rq.queue = NULL; +- return err; + } + + void rxe_srq_cleanup(struct rxe_pool_elem *elem) +-- +2.51.0 + diff --git a/queue-6.6/regulator-core-disable-supply-if-enabling-main-regul.patch b/queue-6.6/regulator-core-disable-supply-if-enabling-main-regul.patch new file mode 100644 index 0000000000..7e2770bd54 --- /dev/null +++ b/queue-6.6/regulator-core-disable-supply-if-enabling-main-regul.patch @@ -0,0 +1,79 @@ +From 08b670bef85172f632219a3cf63347b0bd232098 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Nov 2025 18:10:08 +0100 +Subject: regulator: core: disable supply if enabling main regulator fails + +From: Gabor Juhos + +[ Upstream commit fb1ebb10468da414d57153ddebaab29c38ef1a78 ] + +For 'always-on' and 'boot-on' regulators, the set_machine_constraints() +may enable supply before enabling the main regulator, however if the +latter fails, the function returns with an error but the supply remains +enabled. + +When this happens, the regulator_register() function continues on the +error path where it puts the supply regulator. Since enabling the supply +is not balanced with a disable call, a warning similar to the following +gets issued from _regulator_put(): + + [ 1.603889] WARNING: CPU: 2 PID: 44 at _regulator_put+0x8c/0xa0 + [ 1.603908] Modules linked in: + [ 1.603926] CPU: 2 UID: 0 PID: 44 Comm: kworker/u16:3 Not tainted 6.18.0-rc4 #0 NONE + [ 1.603938] Hardware name: Qualcomm Technologies, Inc. IPQ9574/AP-AL02-C7 (DT) + [ 1.603945] Workqueue: async async_run_entry_fn + [ 1.603958] pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) + [ 1.603967] pc : _regulator_put+0x8c/0xa0 + [ 1.603976] lr : _regulator_put+0x7c/0xa0 + ... + [ 1.604140] Call trace: + [ 1.604145] _regulator_put+0x8c/0xa0 (P) + [ 1.604156] regulator_register+0x2ec/0xbf0 + [ 1.604166] devm_regulator_register+0x60/0xb0 + [ 1.604178] rpm_reg_probe+0x120/0x208 + [ 1.604187] platform_probe+0x64/0xa8 + ... + +In order to avoid this, change the set_machine_constraints() function to +disable the supply if enabling the main regulator fails. + +Fixes: 05f224ca6693 ("regulator: core: Clean enabling always-on regulators + their supplies") +Signed-off-by: Gabor Juhos +Link: https://patch.msgid.link/20251107-regulator-disable-supply-v1-1-c95f0536f1b5@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 1d49612eeb7e5..465f4f870162f 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1653,6 +1653,8 @@ static int set_machine_constraints(struct regulator_dev *rdev) + * and we have control then make sure it is enabled. + */ + if (rdev->constraints->always_on || rdev->constraints->boot_on) { ++ bool supply_enabled = false; ++ + /* If we want to enable this regulator, make sure that we know + * the supplying regulator. + */ +@@ -1672,11 +1674,14 @@ static int set_machine_constraints(struct regulator_dev *rdev) + rdev->supply = NULL; + return ret; + } ++ supply_enabled = true; + } + + ret = _regulator_do_enable(rdev); + if (ret < 0 && ret != -EINVAL) { + rdev_err(rdev, "failed to enable: %pe\n", ERR_PTR(ret)); ++ if (supply_enabled) ++ regulator_disable(rdev->supply); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.6/regulator-core-protect-regulator_supply_alias_list-w.patch b/queue-6.6/regulator-core-protect-regulator_supply_alias_list-w.patch new file mode 100644 index 0000000000..e7937daf0d --- /dev/null +++ b/queue-6.6/regulator-core-protect-regulator_supply_alias_list-w.patch @@ -0,0 +1,108 @@ +From 499fa1ec2d9fc9fec82ef693872eca2e33e886f8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 10:57:16 +0800 +Subject: regulator: core: Protect regulator_supply_alias_list with + regulator_list_mutex + +From: sparkhuang + +[ Upstream commit 0cc15a10c3b4ab14cd71b779fd5c9ca0cb2bc30d ] + +regulator_supply_alias_list was accessed without any locking in +regulator_supply_alias(), regulator_register_supply_alias(), and +regulator_unregister_supply_alias(). Concurrent registration, +unregistration and lookups can race, leading to: + +1 use-after-free if an alias entry is removed while being read, +2 duplicate entries when two threads register the same alias, +3 inconsistent alias mappings observed by consumers. + +Protect all traversals, insertions and deletions on +regulator_supply_alias_list with the existing regulator_list_mutex. + +Fixes: a06ccd9c3785f ("regulator: core: Add ability to create a lookup alias for supply") +Signed-off-by: sparkhuang +Reviewed-by: Charles Keepax +Link: https://patch.msgid.link/20251127025716.5440-1-huangshaobo3@xiaomi.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/regulator/core.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 465f4f870162f..23cdf220ca7db 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -1970,6 +1970,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(*dev, *supply); + if (map) { + dev_dbg(*dev, "Mapping supply %s to %s,%s\n", +@@ -1978,6 +1979,7 @@ static void regulator_supply_alias(struct device **dev, const char **supply) + *dev = map->alias_dev; + *supply = map->alias_supply; + } ++ mutex_unlock(®ulator_list_mutex); + } + + static int regulator_match(struct device *dev, const void *data) +@@ -2456,22 +2458,26 @@ int regulator_register_supply_alias(struct device *dev, const char *id, + const char *alias_id) + { + struct regulator_supply_alias *map; ++ struct regulator_supply_alias *new_map; + +- map = regulator_find_supply_alias(dev, id); +- if (map) +- return -EEXIST; +- +- map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); +- if (!map) ++ new_map = kzalloc(sizeof(struct regulator_supply_alias), GFP_KERNEL); ++ if (!new_map) + return -ENOMEM; + +- map->src_dev = dev; +- map->src_supply = id; +- map->alias_dev = alias_dev; +- map->alias_supply = alias_id; +- +- list_add(&map->list, ®ulator_supply_alias_list); ++ mutex_lock(®ulator_list_mutex); ++ map = regulator_find_supply_alias(dev, id); ++ if (map) { ++ mutex_unlock(®ulator_list_mutex); ++ kfree(new_map); ++ return -EEXIST; ++ } + ++ new_map->src_dev = dev; ++ new_map->src_supply = id; ++ new_map->alias_dev = alias_dev; ++ new_map->alias_supply = alias_id; ++ list_add(&new_map->list, ®ulator_supply_alias_list); ++ mutex_unlock(®ulator_list_mutex); + pr_info("Adding alias for supply %s,%s -> %s,%s\n", + id, dev_name(dev), alias_id, dev_name(alias_dev)); + +@@ -2491,11 +2497,13 @@ void regulator_unregister_supply_alias(struct device *dev, const char *id) + { + struct regulator_supply_alias *map; + ++ mutex_lock(®ulator_list_mutex); + map = regulator_find_supply_alias(dev, id); + if (map) { + list_del(&map->list); + kfree(map); + } ++ mutex_unlock(®ulator_list_mutex); + } + EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias); + +-- +2.51.0 + diff --git a/queue-6.6/reinstate-resource-avoid-unnecessary-lookups-in-find.patch b/queue-6.6/reinstate-resource-avoid-unnecessary-lookups-in-find.patch new file mode 100644 index 0000000000..c45b4e6713 --- /dev/null +++ b/queue-6.6/reinstate-resource-avoid-unnecessary-lookups-in-find.patch @@ -0,0 +1,85 @@ +From d8d879ef92c7a62189dd89b9f8c344cfb09f7660 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 16:53:49 +0000 +Subject: Reinstate "resource: avoid unnecessary lookups in + find_next_iomem_res()" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilias Stamatis + +[ Upstream commit 6fb3acdebf65a72df0a95f9fd2c901ff2bc9a3a2 ] + +Commit 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only +logic") removed an optimization introduced by commit 756398750e11 +("resource: avoid unnecessary lookups in find_next_iomem_res()"). That +was not called out in the message of the first commit explicitly so it's +not entirely clear whether removing the optimization happened +inadvertently or not. + +As the original commit message of the optimization explains there is no +point considering the children of a subtree in find_next_iomem_res() if +the top level range does not match. + +Reinstating the optimization results in performance improvements in +systems where /proc/iomem is ~5k lines long. Calling mmap() on /dev/mem +in such platforms takes 700-1500μs without the optimisation and 10-50μs +with the optimisation. + +Note that even though commit 97523a4edb7b removed the 'sibling_only' +parameter from next_resource(), newer kernels have basically reinstated it +under the name 'skip_children'. + +Link: https://lore.kernel.org/all/20251124165349.3377826-1-ilstam@amazon.com/T/#u +Fixes: 97523a4edb7b ("kernel/resource: remove first_lvl / siblings_only logic") +Signed-off-by: Ilias Stamatis +Acked-by: David Hildenbrand (Red Hat) +Cc: Andriy Shevchenko +Cc: Baoquan He +Cc: "Huang, Ying" +Cc: Nadav Amit +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 67410132b40e1..dca8581eb3992 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -336,6 +336,8 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + unsigned long flags, unsigned long desc, + struct resource *res) + { ++ /* Skip children until we find a top level range that matches */ ++ bool skip_children = true; + struct resource *p; + + if (!res) +@@ -346,7 +348,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for_each_resource(&iomem_resource, p, false) { ++ for_each_resource(&iomem_resource, p, skip_children) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -357,6 +359,12 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + ++ /* ++ * We found a top level range that matches what we are looking ++ * for. Time to start checking children too. ++ */ ++ skip_children = false; ++ + /* Found a match, break */ + if (is_type_match(p, flags, desc)) + break; +-- +2.51.0 + diff --git a/queue-6.6/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch b/queue-6.6/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch new file mode 100644 index 0000000000..fa339f4e16 --- /dev/null +++ b/queue-6.6/remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch @@ -0,0 +1,57 @@ +From df9218f3cf34dbbae9d05dc9dc2f272c06d35816 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:32:05 -0600 +Subject: remoteproc: qcom_q6v5_wcss: fix parsing of qcom,halt-regs + +From: Alexandru Gagniuc + +[ Upstream commit 7e81fa8d809ed1e67ae9ecd52d20a20c2c65d877 ] + +The "qcom,halt-regs" consists of a phandle reference followed by the +three offsets within syscon for halt registers. Thus, we need to +request 4 integers from of_property_read_variable_u32_array(), with +the halt_reg ofsets at indexes 1, 2, and 3. Offset 0 is the phandle. + +With MAX_HALT_REG at 3, of_property_read_variable_u32_array() returns +-EOVERFLOW, causing .probe() to fail. + +Increase MAX_HALT_REG to 4, and update the indexes accordingly. + +Fixes: 0af65b9b915e ("remoteproc: qcom: wcss: Add non pas wcss Q6 support for QCS404") +Signed-off-by: Alexandru Gagniuc +Link: https://lore.kernel.org/r/20251129013207.3981517-1-mr.nuke.me@gmail.com +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/remoteproc/qcom_q6v5_wcss.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c +index cff1fa07d1def..f80d701225a18 100644 +--- a/drivers/remoteproc/qcom_q6v5_wcss.c ++++ b/drivers/remoteproc/qcom_q6v5_wcss.c +@@ -85,7 +85,7 @@ + #define TCSR_WCSS_CLK_MASK 0x1F + #define TCSR_WCSS_CLK_ENABLE 0x14 + +-#define MAX_HALT_REG 3 ++#define MAX_HALT_REG 4 + enum { + WCSS_IPQ8074, + WCSS_QCS404, +@@ -863,9 +863,9 @@ static int q6v5_wcss_init_mmio(struct q6v5_wcss *wcss, + return -EINVAL; + } + +- wcss->halt_q6 = halt_reg[0]; +- wcss->halt_wcss = halt_reg[1]; +- wcss->halt_nc = halt_reg[2]; ++ wcss->halt_q6 = halt_reg[1]; ++ wcss->halt_wcss = halt_reg[2]; ++ wcss->halt_nc = halt_reg[3]; + + return 0; + } +-- +2.51.0 + diff --git a/queue-6.6/resource-introduce-is_type_match-helper-and-use-it.patch b/queue-6.6/resource-introduce-is_type_match-helper-and-use-it.patch new file mode 100644 index 0000000000..a0dcc82b77 --- /dev/null +++ b/queue-6.6/resource-introduce-is_type_match-helper-and-use-it.patch @@ -0,0 +1,91 @@ +From e65c9441f25bf82f6b70cf224e44d231fee17ae2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:35 +0300 +Subject: resource: introduce is_type_match() helper and use it + +From: Andy Shevchenko + +[ Upstream commit ba1eccc114ffc62c4495a5e15659190fa2c42308 ] + +There are already a couple of places where we may replace a few lines of +code by calling a helper, which increases readability while deduplicating +the code. + +Introduce is_type_match() helper and use it. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-3-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 23 ++++++++++------------- + 1 file changed, 10 insertions(+), 13 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index dcc3b564c0537..67410132b40e1 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -310,6 +310,11 @@ int release_resource(struct resource *old) + + EXPORT_SYMBOL(release_resource); + ++static bool is_type_match(struct resource *p, unsigned long flags, unsigned long desc) ++{ ++ return (p->flags & flags) == flags && (desc == IORES_DESC_NONE || desc == p->desc); ++} ++ + /** + * find_next_iomem_res - Finds the lowest iomem resource that covers part of + * [@start..@end]. +@@ -352,13 +357,9 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + if (p->end < start) + continue; + +- if ((p->flags & flags) != flags) +- continue; +- if ((desc != IORES_DESC_NONE) && (desc != p->desc)) +- continue; +- + /* Found a match, break */ +- break; ++ if (is_type_match(p, flags, desc)) ++ break; + } + + if (p) { +@@ -501,7 +502,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + int type = 0; int other = 0; + struct resource *p, *dp; + struct resource res, o; +- bool is_type, covered; ++ bool covered; + + res.start = start; + res.end = start + size - 1; +@@ -509,9 +510,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for (p = parent->child; p ; p = p->sibling) { + if (!resource_intersection(p, &res, &o)) + continue; +- is_type = (p->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == p->desc); +- if (is_type) { ++ if (is_type_match(p, flags, desc)) { + type++; + continue; + } +@@ -531,9 +530,7 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +- is_type = (dp->flags & flags) == flags && +- (desc == IORES_DESC_NONE || desc == dp->desc); +- if (is_type) { ++ if (is_type_match(dp, flags, desc)) { + type++; + /* + * Range from 'o.start' to 'dp->start' +-- +2.51.0 + diff --git a/queue-6.6/resource-replace-open-coded-resource_intersection.patch b/queue-6.6/resource-replace-open-coded-resource_intersection.patch new file mode 100644 index 0000000000..66d57e2a5b --- /dev/null +++ b/queue-6.6/resource-replace-open-coded-resource_intersection.patch @@ -0,0 +1,88 @@ +From e6c3f1e79c394683001bfffb9880f80d36553523 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 25 Sep 2024 18:43:34 +0300 +Subject: resource: replace open coded resource_intersection() + +From: Andy Shevchenko + +[ Upstream commit 5c1edea773c98707fbb23d1df168bcff52f61e4b ] + +Patch series "resource: A couple of cleanups". + +A couple of ad-hoc cleanups since there was a recent development of +the code in question. No functional changes intended. + +This patch (of 2): + +__region_intersects() uses open coded resource_intersection(). Replace it +with existing API which also make more clear what we are checking. + +Link: https://lkml.kernel.org/r/20240925154355.1170859-1-andriy.shevchenko@linux.intel.com +Link: https://lkml.kernel.org/r/20240925154355.1170859-2-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Cc: Rasmus Villemoes +Signed-off-by: Andrew Morton +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 79fba72cb7d2e..dcc3b564c0537 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -498,17 +498,16 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + size_t size, unsigned long flags, + unsigned long desc) + { +- resource_size_t ostart, oend; + int type = 0; int other = 0; + struct resource *p, *dp; ++ struct resource res, o; + bool is_type, covered; +- struct resource res; + + res.start = start; + res.end = start + size - 1; + + for (p = parent->child; p ; p = p->sibling) { +- if (!resource_overlaps(p, &res)) ++ if (!resource_intersection(p, &res, &o)) + continue; + is_type = (p->flags & flags) == flags && + (desc == IORES_DESC_NONE || desc == p->desc); +@@ -529,8 +528,6 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + * |-- "System RAM" --||-- "CXL Window 0a" --| + */ + covered = false; +- ostart = max(res.start, p->start); +- oend = min(res.end, p->end); + for_each_resource(p, dp, false) { + if (!resource_overlaps(dp, &res)) + continue; +@@ -539,17 +536,17 @@ static int __region_intersects(struct resource *parent, resource_size_t start, + if (is_type) { + type++; + /* +- * Range from 'ostart' to 'dp->start' ++ * Range from 'o.start' to 'dp->start' + * isn't covered by matched resource. + */ +- if (dp->start > ostart) ++ if (dp->start > o.start) + break; +- if (dp->end >= oend) { ++ if (dp->end >= o.end) { + covered = true; + break; + } + /* Remove covered range */ +- ostart = max(ostart, dp->end + 1); ++ o.start = max(o.start, dp->end + 1); + } + } + if (!covered) +-- +2.51.0 + diff --git a/queue-6.6/resource-reuse-for_each_resource-macro.patch b/queue-6.6/resource-reuse-for_each_resource-macro.patch new file mode 100644 index 0000000000..07bd88e587 --- /dev/null +++ b/queue-6.6/resource-reuse-for_each_resource-macro.patch @@ -0,0 +1,101 @@ +From c2957e913453efcfd7dca7e152a5f331576f97cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 12 Sep 2023 19:53:10 +0300 +Subject: resource: Reuse for_each_resource() macro + +From: Andy Shevchenko + +[ Upstream commit 441f0dd8fa035a2c7cfe972047bb905d3be05c1b ] + +We have a few places where for_each_resource() is open coded. +Replace that by the macro. This makes code easier to read and +understand. + +With this, compile r_next() only for CONFIG_PROC_FS=y. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20230912165312.402422-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 6fb3acdebf65 ("Reinstate "resource: avoid unnecessary lookups in find_next_iomem_res()"") +Signed-off-by: Sasha Levin +--- + kernel/resource.c | 34 +++++++++++++++++++--------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/kernel/resource.c b/kernel/resource.c +index 6506839f8a811..79fba72cb7d2e 100644 +--- a/kernel/resource.c ++++ b/kernel/resource.c +@@ -77,13 +77,6 @@ static struct resource *next_resource_skip_children(struct resource *p) + (_p) = (_skip_children) ? next_resource_skip_children(_p) : \ + next_resource(_p)) + +-static void *r_next(struct seq_file *m, void *v, loff_t *pos) +-{ +- struct resource *p = v; +- (*pos)++; +- return (void *)next_resource(p); +-} +- + #ifdef CONFIG_PROC_FS + + enum { MAX_IORES_LEVEL = 5 }; +@@ -91,14 +84,26 @@ enum { MAX_IORES_LEVEL = 5 }; + static void *r_start(struct seq_file *m, loff_t *pos) + __acquires(resource_lock) + { +- struct resource *p = pde_data(file_inode(m->file)); +- loff_t l = 0; ++ struct resource *root = pde_data(file_inode(m->file)); ++ struct resource *p; ++ loff_t l = *pos; ++ + read_lock(&resource_lock); +- for (p = p->child; p && l < *pos; p = r_next(m, p, &l)) +- ; ++ for_each_resource(root, p, false) { ++ if (l-- == 0) ++ break; ++ } ++ + return p; + } + ++static void *r_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ struct resource *p = v; ++ (*pos)++; ++ return (void *)next_resource(p); ++} ++ + static void r_stop(struct seq_file *m, void *v) + __releases(resource_lock) + { +@@ -336,7 +341,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end, + + read_lock(&resource_lock); + +- for (p = iomem_resource.child; p; p = next_resource(p)) { ++ for_each_resource(&iomem_resource, p, false) { + /* If we passed the resource we are looking for, stop */ + if (p->start > end) { + p = NULL; +@@ -1684,13 +1689,12 @@ __setup("reserve=", reserve_setup); + */ + int iomem_map_sanity_check(resource_size_t addr, unsigned long size) + { +- struct resource *p = &iomem_resource; + resource_size_t end = addr + size - 1; ++ struct resource *p; + int err = 0; +- loff_t l; + + read_lock(&resource_lock); +- for (p = p->child; p ; p = r_next(NULL, p, &l)) { ++ for_each_resource(&iomem_resource, p, false) { + /* + * We can probably skip the resources without + * IORESOURCE_IO attribute? +-- +2.51.0 + diff --git a/queue-6.6/revert-mtd-rawnand-marvell-fix-layouts.patch b/queue-6.6/revert-mtd-rawnand-marvell-fix-layouts.patch new file mode 100644 index 0000000000..f0ac190a7a --- /dev/null +++ b/queue-6.6/revert-mtd-rawnand-marvell-fix-layouts.patch @@ -0,0 +1,51 @@ +From b43bfc9177e64ef42c77df0b7b4b518ec9cfbb37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 13:19:41 +1300 +Subject: Revert "mtd: rawnand: marvell: fix layouts" + +From: Aryan Srivastava + +[ Upstream commit fbd72cb463fdea3a0c900dd5d6e813cdebc3a73c ] + +This reverts commit e6a30d0c48a1e8a68f1cc413bee65302ab03ddfb. + +This change resulted in the 8bit ECC layouts having the incorrect amount +of read/write chunks, the last spare bytes chunk would always be missed. + +Fixes: e6a30d0c48a1 ("mtd: rawnand: marvell: fix layouts") +Signed-off-by: Aryan Srivastava +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/nand/raw/marvell_nand.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c +index 93d8c6da555b9..b841a81cb1282 100644 +--- a/drivers/mtd/nand/raw/marvell_nand.c ++++ b/drivers/mtd/nand/raw/marvell_nand.c +@@ -290,13 +290,16 @@ static const struct marvell_hw_ecc_layout marvell_nfc_layouts[] = { + MARVELL_LAYOUT( 2048, 512, 4, 1, 1, 2048, 32, 30, 0, 0, 0), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,32, 30), + MARVELL_LAYOUT( 2048, 512, 8, 2, 1, 1024, 0, 30,1024,64, 30), +- MARVELL_LAYOUT( 2048, 512, 16, 4, 4, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 2048, 512, 12, 3, 2, 704, 0, 30,640, 0, 30), ++ MARVELL_LAYOUT( 2048, 512, 16, 5, 4, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 4096, 512, 4, 2, 2, 2048, 32, 30, 0, 0, 0), +- MARVELL_LAYOUT( 4096, 512, 8, 4, 4, 1024, 0, 30, 0, 64, 30), +- MARVELL_LAYOUT( 4096, 512, 16, 8, 8, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 8, 5, 4, 1024, 0, 30, 0, 64, 30), ++ MARVELL_LAYOUT( 4096, 512, 12, 6, 5, 704, 0, 30,576, 32, 30), ++ MARVELL_LAYOUT( 4096, 512, 16, 9, 8, 512, 0, 30, 0, 32, 30), + MARVELL_LAYOUT( 8192, 512, 4, 4, 4, 2048, 0, 30, 0, 0, 0), +- MARVELL_LAYOUT( 8192, 512, 8, 8, 8, 1024, 0, 30, 0, 160, 30), +- MARVELL_LAYOUT( 8192, 512, 16, 16, 16, 512, 0, 30, 0, 32, 30), ++ MARVELL_LAYOUT( 8192, 512, 8, 9, 8, 1024, 0, 30, 0, 160, 30), ++ MARVELL_LAYOUT( 8192, 512, 12, 12, 11, 704, 0, 30,448, 64, 30), ++ MARVELL_LAYOUT( 8192, 512, 16, 17, 16, 512, 0, 30, 0, 32, 30), + }; + + /** +-- +2.51.0 + diff --git a/queue-6.6/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch b/queue-6.6/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch new file mode 100644 index 0000000000..7e98bbde46 --- /dev/null +++ b/queue-6.6/risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch @@ -0,0 +1,84 @@ +From 8e75b596186f7a1b42c0d94b548b9bcf2185dd34 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 21 Nov 2025 21:35:43 +0800 +Subject: RISC-V: KVM: Fix guest page fault within HLV* instructions + +From: Fangyu Yu + +[ Upstream commit 974555d6e417974e63444266e495a06d06c23af5 ] + +When executing HLV* instructions at the HS mode, a guest page fault +may occur when a g-stage page table migration between triggering the +virtual instruction exception and executing the HLV* instruction. + +This may be a corner case, and one simpler way to handle this is to +re-execute the instruction where the virtual instruction exception +occurred, and the guest page fault will be automatically handled. + +Fixes: b91f0e4cb8a3 ("RISC-V: KVM: Factor-out instruction emulation into separate sources") +Signed-off-by: Fangyu Yu +Reviewed-by: Anup Patel +Link: https://lore.kernel.org/r/20251121133543.46822-1-fangyu.yu@linux.alibaba.com +Signed-off-by: Anup Patel +Signed-off-by: Sasha Levin +--- + arch/riscv/kvm/vcpu_insn.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index 7a6abed41bc17..703d1e0fce774 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -396,6 +396,22 @@ static int system_opcode_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + return (rc <= 0) ? rc : 1; + } + ++static bool is_load_guest_page_fault(unsigned long scause) ++{ ++ /** ++ * If a g-stage page fault occurs, the direct approach ++ * is to let the g-stage page fault handler handle it ++ * naturally, however, calling the g-stage page fault ++ * handler here seems rather strange. ++ * Considering this is a corner case, we can directly ++ * return to the guest and re-execute the same PC, this ++ * will trigger a g-stage page fault again and then the ++ * regular g-stage page fault handler will populate ++ * g-stage page table. ++ */ ++ return (scause == EXC_LOAD_GUEST_PAGE_FAULT); ++} ++ + /** + * kvm_riscv_vcpu_virtual_insn -- Handle virtual instruction trap + * +@@ -421,6 +437,8 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + return 1; +@@ -476,6 +494,8 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +@@ -602,6 +622,8 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, ct->sepc, + &utrap); + if (utrap.scause) { ++ if (is_load_guest_page_fault(utrap.scause)) ++ return 1; + /* Redirect trap if we failed to read instruction */ + utrap.sepc = ct->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); +-- +2.51.0 + diff --git a/queue-6.6/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch b/queue-6.6/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch new file mode 100644 index 0000000000..b9cc295f2b --- /dev/null +++ b/queue-6.6/s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch @@ -0,0 +1,48 @@ +From 35fdb448fbaeb95c1cf2554b03096248e39f7bcf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Oct 2025 12:24:33 +0200 +Subject: s390/ap: Don't leak debug feature files if AP instructions are not + available + +From: Heiko Carstens + +[ Upstream commit 020d5dc57874e58d3ebae398f3fe258f029e3d06 ] + +If no AP instructions are available the AP bus module leaks registered +debug feature files. Change function call order to fix this. + +Fixes: cccd85bfb7bf ("s390/zcrypt: Rework debug feature invocations.") +Reviewed-by: Harald Freudenberger +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + drivers/s390/crypto/ap_bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c +index 93351452184ab..97cbf233a543d 100644 +--- a/drivers/s390/crypto/ap_bus.c ++++ b/drivers/s390/crypto/ap_bus.c +@@ -2235,15 +2235,15 @@ static int __init ap_module_init(void) + { + int rc; + +- rc = ap_debug_init(); +- if (rc) +- return rc; +- + if (!ap_instructions_available()) { + pr_warn("The hardware system does not support AP instructions\n"); + return -ENODEV; + } + ++ rc = ap_debug_init(); ++ if (rc) ++ return rc; ++ + /* init ap_queue hashtable */ + hash_init(ap_queues); + +-- +2.51.0 + diff --git a/queue-6.6/s390-smp-fix-fallback-cpu-detection.patch b/queue-6.6/s390-smp-fix-fallback-cpu-detection.patch new file mode 100644 index 0000000000..e829b33672 --- /dev/null +++ b/queue-6.6/s390-smp-fix-fallback-cpu-detection.patch @@ -0,0 +1,50 @@ +From 0089055d69da3329a7572e574a9750a336f8e13e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 20 Oct 2025 16:17:54 +0200 +Subject: s390/smp: Fix fallback CPU detection + +From: Heiko Carstens + +[ Upstream commit 07a75d08cfa1b883a6e1256666e5f0617ee99231 ] + +In case SCLP CPU detection does not work a fallback mechanism using SIGP is +in place. Since a cleanup this does not work correctly anymore: new CPUs +are only considered if their type matches the boot CPU. + +Before the cleanup the information if a CPU type should be considered was +also part of a structure generated by the fallback mechanism and indicated +that a CPU type should not be considered when adding CPUs. + +Since the rework a global SCLP state is used instead. If the global SCLP +state indicates that the CPU type should be considered and the fallback +mechanism is used, there may be a mismatch with CPU types if CPUs are +added. This can lead to a system with only a single CPU even tough there +are many more CPUs. + +Address this by simply copying the boot cpu type into the generated data +structure from the fallback mechanism. + +Reported-by: Alexander Egorenkov +Fixes: d08d94306e90 ("s390/smp: cleanup core vs. cpu in the SCLP interface") +Reviewed-by: Mete Durlu +Signed-off-by: Heiko Carstens +Signed-off-by: Sasha Levin +--- + arch/s390/kernel/smp.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c +index c63be2efd6895..1970c90775973 100644 +--- a/arch/s390/kernel/smp.c ++++ b/arch/s390/kernel/smp.c +@@ -759,6 +759,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early) + continue; + info->core[info->configured].core_id = + address >> smp_cpu_mt_shift; ++ info->core[info->configured].type = boot_core_type; + info->configured++; + } + info->combined = info->configured; +-- +2.51.0 + diff --git a/queue-6.6/sched-fair-forfeit-vruntime-on-yield.patch b/queue-6.6/sched-fair-forfeit-vruntime-on-yield.patch new file mode 100644 index 0000000000..301efd4021 --- /dev/null +++ b/queue-6.6/sched-fair-forfeit-vruntime-on-yield.patch @@ -0,0 +1,68 @@ +From da63e463bb7ddfa3f9cfa92e2c62daba0edba1ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Sep 2025 17:05:28 +0200 +Subject: sched/fair: Forfeit vruntime on yield + +From: Fernand Sieber + +[ Upstream commit 79104becf42baeeb4a3f2b106f954b9fc7c10a3c ] + +If a task yields, the scheduler may decide to pick it again. The task in +turn may decide to yield immediately or shortly after, leading to a tight +loop of yields. + +If there's another runnable task as this point, the deadline will be +increased by the slice at each loop. This can cause the deadline to runaway +pretty quickly, and subsequent elevated run delays later on as the task +doesn't get picked again. The reason the scheduler can pick the same task +again and again despite its deadline increasing is because it may be the +only eligible task at that point. + +Fix this by making the task forfeiting its remaining vruntime and pushing +the deadline one slice ahead. This implements yield behavior more +authentically. + +We limit the forfeiting to eligible tasks. This is because core scheduling +prefers running ineligible tasks rather than force idling. As such, without +the condition, we can end up on a yield loop which makes the vruntime +increase rapidly, leading to anomalous run delays later down the line. + +Fixes: 147f3efaa24182 ("sched/fair: Implement an EEVDF-like scheduling policy") +Signed-off-by: Fernand Sieber +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20250401123622.584018-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250911095113.203439-1-sieberf@amazon.com +Link: https://lore.kernel.org/r/20250916140228.452231-1-sieberf@amazon.com +Signed-off-by: Sasha Levin +--- + kernel/sched/fair.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c +index 7f23b866c3d4c..cf3a51f323e32 100644 +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -8614,7 +8614,19 @@ static void yield_task_fair(struct rq *rq) + */ + rq_clock_skip_update(rq); + +- se->deadline += calc_delta_fair(se->slice, se); ++ /* ++ * Forfeit the remaining vruntime, only if the entity is eligible. This ++ * condition is necessary because in core scheduling we prefer to run ++ * ineligible tasks rather than force idling. If this happens we may ++ * end up in a loop where the core scheduler picks the yielding task, ++ * which yields immediately again; without the condition the vruntime ++ * ends up quickly running away. ++ */ ++ if (entity_eligible(cfs_rq, se)) { ++ se->vruntime = se->deadline; ++ se->deadline += calc_delta_fair(se->slice, se); ++ update_min_vruntime(cfs_rq); ++ } + } + + static bool yield_to_task_fair(struct rq *rq, struct task_struct *p) +-- +2.51.0 + diff --git a/queue-6.6/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch b/queue-6.6/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch new file mode 100644 index 0000000000..1b340423ec --- /dev/null +++ b/queue-6.6/scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch @@ -0,0 +1,51 @@ +From 2d466f4edf74a3fd46e25d6376c16af234d72fe0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 15:12:46 +0000 +Subject: scsi: qla2xxx: Fix improper freeing of purex item + +From: Zilin Guan + +[ Upstream commit 78b1a242fe612a755f2158fd206ee6bb577d18ca ] + +In qla2xxx_process_purls_iocb(), an item is allocated via +qla27xx_copy_multiple_pkt(), which internally calls +qla24xx_alloc_purex_item(). + +The qla24xx_alloc_purex_item() function may return a pre-allocated item +from a per-adapter pool for small allocations, instead of dynamically +allocating memory with kzalloc(). + +An error handling path in qla2xxx_process_purls_iocb() incorrectly uses +kfree() to release the item. If the item was from the pre-allocated +pool, calling kfree() on it is a bug that can lead to memory corruption. + +Fix this by using the correct deallocation function, +qla24xx_free_purex_item(), which properly handles both dynamically +allocated and pre-allocated items. + +Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe") +Signed-off-by: Zilin Guan +Reviewed-by: Himanshu Madhani +Link: https://patch.msgid.link/20251113151246.762510-1-zilin@seu.edu.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/qla2xxx/qla_nvme.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/scsi/qla2xxx/qla_nvme.c b/drivers/scsi/qla2xxx/qla_nvme.c +index 080670cb2aa51..38cb3281c6350 100644 +--- a/drivers/scsi/qla2xxx/qla_nvme.c ++++ b/drivers/scsi/qla2xxx/qla_nvme.c +@@ -1293,7 +1293,7 @@ void qla2xxx_process_purls_iocb(void **pkt, struct rsp_que **rsp) + a.reason = FCNVME_RJT_RC_LOGIC; + a.explanation = FCNVME_RJT_EXP_NONE; + xmt_reject = true; +- kfree(item); ++ qla24xx_free_purex_item(item); + goto out; + } + +-- +2.51.0 + diff --git a/queue-6.6/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch b/queue-6.6/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch new file mode 100644 index 0000000000..338edd8ee6 --- /dev/null +++ b/queue-6.6/scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch @@ -0,0 +1,50 @@ +From d86a9529b406aa00a13d82a21d816d471b96bb7f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 11:25:55 +0800 +Subject: scsi: sim710: Fix resource leak by adding missing ioport_unmap() + calls + +From: Haotian Zhang + +[ Upstream commit acd194d9b5bac419e04968ffa44351afabb50bac ] + +The driver calls ioport_map() to map I/O ports in sim710_probe_common() +but never calls ioport_unmap() to release the mapping. This causes +resource leaks in both the error path when request_irq() fails and in +the normal device removal path via sim710_device_remove(). + +Add ioport_unmap() calls in the out_release error path and in +sim710_device_remove(). + +Fixes: 56fece20086e ("[PATCH] finally fix 53c700 to use the generic iomem infrastructure") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251029032555.1476-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sim710.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c +index e519df68d603d..70c75ab1453a1 100644 +--- a/drivers/scsi/sim710.c ++++ b/drivers/scsi/sim710.c +@@ -133,6 +133,7 @@ static int sim710_probe_common(struct device *dev, unsigned long base_addr, + out_put_host: + scsi_host_put(host); + out_release: ++ ioport_unmap(hostdata->base); + release_region(base_addr, 64); + out_free: + kfree(hostdata); +@@ -148,6 +149,7 @@ static int sim710_device_remove(struct device *dev) + + scsi_remove_host(host); + NCR_700_release(host); ++ ioport_unmap(hostdata->base); + kfree(hostdata); + free_irq(host->irq, host); + release_region(host->base, 64); +-- +2.51.0 + diff --git a/queue-6.6/scsi-smartpqi-fix-device-resources-accessed-after-de.patch b/queue-6.6/scsi-smartpqi-fix-device-resources-accessed-after-de.patch new file mode 100644 index 0000000000..a55b968415 --- /dev/null +++ b/queue-6.6/scsi-smartpqi-fix-device-resources-accessed-after-de.patch @@ -0,0 +1,94 @@ +From 5d05710f5f267e82c9d6b3e0961cb04fd9b83346 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 6 Nov 2025 10:38:20 -0600 +Subject: scsi: smartpqi: Fix device resources accessed after device removal + +From: Mike McGowen + +[ Upstream commit b518e86d1a70a88f6592a7c396cf1b93493d1aab ] + +Correct possible race conditions during device removal. + +Previously, a scheduled work item to reset a LUN could still execute +after the device was removed, leading to use-after-free and other +resource access issues. + +This race condition occurs because the abort handler may schedule a LUN +reset concurrently with device removal via sdev_destroy(), leading to +use-after-free and improper access to freed resources. + + - Check in the device reset handler if the device is still present in + the controller's SCSI device list before running; if not, the reset + is skipped. + + - Cancel any pending TMF work that has not started in sdev_destroy(). + + - Ensure device freeing in sdev_destroy() is done while holding the + LUN reset mutex to avoid races with ongoing resets. + +Fixes: 2d80f4054f7f ("scsi: smartpqi: Update deleting a LUN via sysfs") +Reviewed-by: Scott Teel +Reviewed-by: Scott Benesh +Signed-off-by: Mike McGowen +Signed-off-by: Don Brace +Link: https://patch.msgid.link/20251106163823.786828-3-don.brace@microchip.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/smartpqi/smartpqi_init.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c +index 0af2d366c85f9..0cdeb7aa55020 100644 +--- a/drivers/scsi/smartpqi/smartpqi_init.c ++++ b/drivers/scsi/smartpqi/smartpqi_init.c +@@ -6366,10 +6366,22 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev + + static int pqi_device_reset_handler(struct pqi_ctrl_info *ctrl_info, struct pqi_scsi_dev *device, u8 lun, struct scsi_cmnd *scmd, u8 scsi_opcode) + { ++ unsigned long flags; + int rc; + + mutex_lock(&ctrl_info->lun_reset_mutex); + ++ spin_lock_irqsave(&ctrl_info->scsi_device_list_lock, flags); ++ if (pqi_find_scsi_dev(ctrl_info, device->bus, device->target, device->lun) == NULL) { ++ dev_warn(&ctrl_info->pci_dev->dev, ++ "skipping reset of scsi %d:%d:%d:%u, device has been removed\n", ++ ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ctrl_info->scsi_device_list_lock, flags); ++ + dev_err(&ctrl_info->pci_dev->dev, + "resetting scsi %d:%d:%d:%u SCSI cmd at %p due to cmd opcode 0x%02x\n", + ctrl_info->scsi_host->host_no, device->bus, device->target, lun, scmd, scsi_opcode); +@@ -6549,7 +6561,9 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + { + struct pqi_ctrl_info *ctrl_info; + struct pqi_scsi_dev *device; ++ struct pqi_tmf_work *tmf_work; + int mutex_acquired; ++ unsigned int lun; + unsigned long flags; + + ctrl_info = shost_to_hba(sdev->host); +@@ -6576,8 +6590,13 @@ static void pqi_slave_destroy(struct scsi_device *sdev) + + mutex_unlock(&ctrl_info->scan_mutex); + ++ for (lun = 0, tmf_work = device->tmf_work; lun < PQI_MAX_LUNS_PER_DEVICE; lun++, tmf_work++) ++ cancel_work_sync(&tmf_work->work_struct); ++ ++ mutex_lock(&ctrl_info->lun_reset_mutex); + pqi_dev_info(ctrl_info, "removed", device); + pqi_free_device(device); ++ mutex_unlock(&ctrl_info->lun_reset_mutex); + } + + static int pqi_getpciinfo_ioctl(struct pqi_ctrl_info *ctrl_info, void __user *arg) +-- +2.51.0 + diff --git a/queue-6.6/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch b/queue-6.6/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch new file mode 100644 index 0000000000..3764fb1e90 --- /dev/null +++ b/queue-6.6/scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch @@ -0,0 +1,40 @@ +From db9a754d5923824808f999814df311226baf9679 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 17:48:47 +0800 +Subject: scsi: stex: Fix reboot_notifier leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 20da637eb545b04753e20c675cfe97b04c7b600b ] + +In stex_probe(), register_reboot_notifier() is called at the beginning, +but if any subsequent initialization step fails, the function returns +without unregistering the notifier, resulting in a resource leak. + +Add unregister_reboot_notifier() in the out_disable error path to ensure +proper cleanup on all failure paths. + +Fixes: 61b745fa63db ("scsi: stex: Add S6 support") +Signed-off-by: Haotian Zhang +Link: https://patch.msgid.link/20251104094847.270-1-vulab@iscas.ac.cn +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/stex.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c +index 8ffb75be99bc8..879b090fb39ea 100644 +--- a/drivers/scsi/stex.c ++++ b/drivers/scsi/stex.c +@@ -1846,6 +1846,7 @@ static int stex_probe(struct pci_dev *pdev, const struct pci_device_id *id) + out_scsi_host_put: + scsi_host_put(host); + out_disable: ++ unregister_reboot_notifier(&stex_notifier); + pci_disable_device(pdev); + + return err; +-- +2.51.0 + diff --git a/queue-6.6/scsi-target-do-not-write-nul-characters-into-ascii-c.patch b/queue-6.6/scsi-target-do-not-write-nul-characters-into-ascii-c.patch new file mode 100644 index 0000000000..08ecedd46c --- /dev/null +++ b/queue-6.6/scsi-target-do-not-write-nul-characters-into-ascii-c.patch @@ -0,0 +1,36 @@ +From 03522ec84ad7861ee945be1480ad22b7270dfd94 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 27 Oct 2025 11:46:38 -0700 +Subject: scsi: target: Do not write NUL characters into ASCII configfs output + +From: Bart Van Assche + +[ Upstream commit c03b55f235e283cae49c88b9602fd11096b92eba ] + +NUL characters are not allowed in ASCII configfs output. Hence this +patch. + +Fixes: c66ac9db8d4a ("[SCSI] target: Add LIO target core v4.0.0-rc6") +Signed-off-by: Bart Van Assche +Link: https://patch.msgid.link/20251027184639.3501254-2-bvanassche@acm.org +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/target/target_core_configfs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/target/target_core_configfs.c b/drivers/target/target_core_configfs.c +index eddcfd09c05b8..6ec98dfd1f31c 100644 +--- a/drivers/target/target_core_configfs.c ++++ b/drivers/target/target_core_configfs.c +@@ -2736,7 +2736,6 @@ static ssize_t target_lu_gp_members_show(struct config_item *item, char *page) + cur_len = snprintf(buf, LU_GROUP_NAME_BUF, "%s/%s\n", + config_item_name(&hba->hba_group.cg_item), + config_item_name(&dev->dev_group.cg_item)); +- cur_len++; /* Extra byte for NULL terminator */ + + if ((cur_len + len) > PAGE_SIZE || cur_len > LU_GROUP_NAME_BUF) { + pr_warn("Ran out of lu_gp_show_attr" +-- +2.51.0 + diff --git a/queue-6.6/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch b/queue-6.6/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch new file mode 100644 index 0000000000..34084bb3c5 --- /dev/null +++ b/queue-6.6/scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch @@ -0,0 +1,46 @@ +From 29883bc52b8e96f0a1e1f994c8517da3c369049a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 8 Nov 2025 00:05:17 +0100 +Subject: scsi: ufs: core: fix incorrect buffer duplication in + ufshcd_read_string_desc() + +From: Bean Huo + +[ Upstream commit d794b499f948801f54d67ddbc34a6eac5a6d150a ] + +The function ufshcd_read_string_desc() was duplicating memory starting +from the beginning of struct uc_string_id, which included the length and +type fields. As a result, the allocated buffer contained unwanted +metadata in addition to the string itself. + +The correct behavior is to duplicate only the Unicode character array in +the structure. Update the code so that only the actual string content is +copied into the new buffer. + +Fixes: 5f57704dbcfe ("scsi: ufs: Use kmemdup in ufshcd_read_string_desc()") +Reviewed-by: Avri Altman +Reviewed-by: Bart Van Assche +Signed-off-by: Bean Huo +Link: https://patch.msgid.link/20251107230518.4060231-3-beanhuo@iokpp.de +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/ufs/core/ufshcd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c +index 01a7c1720ce15..9d6a47abe4bc6 100644 +--- a/drivers/ufs/core/ufshcd.c ++++ b/drivers/ufs/core/ufshcd.c +@@ -3738,7 +3738,7 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, + str[ret++] = '\0'; + + } else { +- str = kmemdup(uc_str, uc_str->len, GFP_KERNEL); ++ str = kmemdup(uc_str->uc, uc_str->len, GFP_KERNEL); + if (!str) { + ret = -ENOMEM; + goto out; +-- +2.51.0 + diff --git a/queue-6.6/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch b/queue-6.6/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch new file mode 100644 index 0000000000..b331fab64b --- /dev/null +++ b/queue-6.6/sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch @@ -0,0 +1,66 @@ +From 3215f7d4c0b2287a7c830351814c3d94c617514f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 23:16:50 +0000 +Subject: sctp: Defer SCTP_DBG_OBJCNT_DEC() to sctp_destroy_sock(). + +From: Kuniyuki Iwashima + +[ Upstream commit 622e8838a29845316668ec2e7648428878df7f9a ] + +SCTP_DBG_OBJCNT_INC() is called only when sctp_init_sock() +returns 0 after successfully allocating sctp_sk(sk)->ep. + +OTOH, SCTP_DBG_OBJCNT_DEC() is called in sctp_close(). + +The code seems to expect that the socket is always exposed +to userspace once SCTP_DBG_OBJCNT_INC() is incremented, but +there is a path where the assumption is not true. + +In sctp_accept(), sctp_sock_migrate() could fail after +sctp_init_sock(). + +Then, sk_common_release() does not call inet_release() nor +sctp_close(). Instead, it calls sk->sk_prot->destroy(). + +Let's move SCTP_DBG_OBJCNT_DEC() from sctp_close() to +sctp_destroy_sock(). + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Kuniyuki Iwashima +Acked-by: Xin Long +Link: https://patch.msgid.link/20251023231751.4168390-2-kuniyu@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/sctp/socket.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sctp/socket.c b/net/sctp/socket.c +index adc04e88f349f..852c4f66eab5d 100644 +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1553,8 +1553,6 @@ static void sctp_close(struct sock *sk, long timeout) + spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); +- +- SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Handle EPIPE error. */ +@@ -5106,9 +5104,12 @@ static void sctp_destroy_sock(struct sock *sk) + sp->do_auto_asconf = 0; + list_del(&sp->auto_asconf_list); + } ++ + sctp_endpoint_free(sp->ep); ++ + sk_sockets_allocated_dec(sk); + sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); ++ SCTP_DBG_OBJCNT_DEC(sock); + } + + /* Triggered when there are no references on the socket anymore */ +-- +2.51.0 + diff --git a/queue-6.6/selftests-bonding-add-delay-before-each-xvlan_over_b.patch b/queue-6.6/selftests-bonding-add-delay-before-each-xvlan_over_b.patch new file mode 100644 index 0000000000..b8efae1d8e --- /dev/null +++ b/queue-6.6/selftests-bonding-add-delay-before-each-xvlan_over_b.patch @@ -0,0 +1,47 @@ +From 496f0ed5b4cffc2eaf68ea0438c919090c1b9428 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 27 Nov 2025 14:33:10 +0000 +Subject: selftests: bonding: add delay before each xvlan_over_bond + connectivity check + +From: Hangbin Liu + +[ Upstream commit 2c28ee720ad14f58eb88a97ec3efe7c5c315ea5d ] + +Jakub reported increased flakiness in bond_macvlan_ipvlan.sh on regular +kernel, while the tests consistently pass on a debug kernel. This suggests +a timing-sensitive issue. + +To mitigate this, introduce a short sleep before each xvlan_over_bond +connectivity check. The delay helps ensure neighbor and route cache +have fully converged before verifying connectivity. + +The sleep interval is kept minimal since check_connection() is invoked +nearly 100 times during the test. + +Fixes: 246af950b940 ("selftests: bonding: add macvlan over bond testing") +Reported-by: Jakub Kicinski +Closes: https://lore.kernel.org/netdev/20251114082014.750edfad@kernel.org +Signed-off-by: Hangbin Liu +Link: https://patch.msgid.link/20251127143310.47740-1-liuhangbin@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + .../testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +index c4711272fe45d..559f300f965aa 100755 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -30,6 +30,7 @@ check_connection() + local message=${3} + RET=0 + ++ sleep 0.25 + ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null + check_err $? "ping failed" + log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" +-- +2.51.0 + diff --git a/queue-6.6/selftests-bonding-add-ipvlan-over-bond-testing.patch b/queue-6.6/selftests-bonding-add-ipvlan-over-bond-testing.patch new file mode 100644 index 0000000000..6063df2b09 --- /dev/null +++ b/queue-6.6/selftests-bonding-add-ipvlan-over-bond-testing.patch @@ -0,0 +1,275 @@ +From 27c615f59a9bb850e276af49604675c4ab268745 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 8 Jan 2025 22:28:19 -0500 +Subject: selftests: bonding: add ipvlan over bond testing + +From: Etienne Champetier + +[ Upstream commit 08ac69b24507ab06871c18adc421c9d4f1008c61 ] + +This rework bond_macvlan.sh into bond_macvlan_ipvlan.sh +We only test bridge mode for macvlan and l2 mode + +]# ./bond_macvlan_ipvlan.sh +TEST: active-backup/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: active-backup/ipvlan_l2: IPv4: client->server [ OK ] +... +TEST: balance-tlb/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: balance-tlb/ipvlan_l2: IPv4: client->server [ OK ] +... +TEST: balance-alb/macvlan_bridge: IPv4: client->server [ OK ] +... +TEST: balance-alb/ipvlan_l2: IPv4: client->server [ OK ] +... + +Signed-off-by: Etienne Champetier +Link: https://patch.msgid.link/20250109032819.326528-3-champetier.etienne@gmail.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") +Signed-off-by: Sasha Levin +--- + .../selftests/drivers/net/bonding/Makefile | 2 +- + .../drivers/net/bonding/bond_macvlan.sh | 99 ------------------- + .../net/bonding/bond_macvlan_ipvlan.sh | 96 ++++++++++++++++++ + .../selftests/drivers/net/bonding/config | 1 + + 4 files changed, 98 insertions(+), 100 deletions(-) + delete mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh + create mode 100755 tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh + +diff --git a/tools/testing/selftests/drivers/net/bonding/Makefile b/tools/testing/selftests/drivers/net/bonding/Makefile +index 8a72bb7de70f4..770aa7345aacd 100644 +--- a/tools/testing/selftests/drivers/net/bonding/Makefile ++++ b/tools/testing/selftests/drivers/net/bonding/Makefile +@@ -10,7 +10,7 @@ TEST_PROGS := \ + mode-2-recovery-updelay.sh \ + bond_options.sh \ + bond-eth-type-change.sh \ +- bond_macvlan.sh ++ bond_macvlan_ipvlan.sh + + TEST_FILES := \ + lag_lib.sh \ +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh +deleted file mode 100755 +index b609fb6231f48..0000000000000 +--- a/tools/testing/selftests/drivers/net/bonding/bond_macvlan.sh ++++ /dev/null +@@ -1,99 +0,0 @@ +-#!/bin/bash +-# SPDX-License-Identifier: GPL-2.0 +-# +-# Test macvlan over balance-alb +- +-lib_dir=$(dirname "$0") +-source ${lib_dir}/bond_topo_2d1c.sh +- +-m1_ns="m1-$(mktemp -u XXXXXX)" +-m2_ns="m1-$(mktemp -u XXXXXX)" +-m1_ip4="192.0.2.11" +-m1_ip6="2001:db8::11" +-m2_ip4="192.0.2.12" +-m2_ip6="2001:db8::12" +- +-cleanup() +-{ +- ip -n ${m1_ns} link del macv0 +- ip netns del ${m1_ns} +- ip -n ${m2_ns} link del macv0 +- ip netns del ${m2_ns} +- +- client_destroy +- server_destroy +- gateway_destroy +-} +- +-check_connection() +-{ +- local ns=${1} +- local target=${2} +- local message=${3:-"macvlan_over_bond"} +- RET=0 +- +- +- ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null +- check_err $? "ping failed" +- log_test "$mode: $message" +-} +- +-macvlan_over_bond() +-{ +- local param="$1" +- RET=0 +- +- # setup new bond mode +- bond_reset "${param}" +- +- ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge +- ip -n ${s_ns} link set macv0 netns ${m1_ns} +- ip -n ${m1_ns} link set dev macv0 up +- ip -n ${m1_ns} addr add ${m1_ip4}/24 dev macv0 +- ip -n ${m1_ns} addr add ${m1_ip6}/24 dev macv0 +- +- ip -n ${s_ns} link add link bond0 name macv0 type macvlan mode bridge +- ip -n ${s_ns} link set macv0 netns ${m2_ns} +- ip -n ${m2_ns} link set dev macv0 up +- ip -n ${m2_ns} addr add ${m2_ip4}/24 dev macv0 +- ip -n ${m2_ns} addr add ${m2_ip6}/24 dev macv0 +- +- sleep 2 +- +- check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" +- check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" +- check_connection "${c_ns}" "${m1_ip4}" "IPv4: client->macvlan_1" +- check_connection "${c_ns}" "${m1_ip6}" "IPv6: client->macvlan_1" +- check_connection "${c_ns}" "${m2_ip4}" "IPv4: client->macvlan_2" +- check_connection "${c_ns}" "${m2_ip6}" "IPv6: client->macvlan_2" +- check_connection "${m1_ns}" "${m2_ip4}" "IPv4: macvlan_1->macvlan_2" +- check_connection "${m1_ns}" "${m2_ip6}" "IPv6: macvlan_1->macvlan_2" +- +- +- sleep 5 +- +- check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" +- check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" +- check_connection "${m1_ns}" "${c_ip4}" "IPv4: macvlan_1->client" +- check_connection "${m1_ns}" "${c_ip6}" "IPv6: macvlan_1->client" +- check_connection "${m2_ns}" "${c_ip4}" "IPv4: macvlan_2->client" +- check_connection "${m2_ns}" "${c_ip6}" "IPv6: macvlan_2->client" +- check_connection "${m2_ns}" "${m1_ip4}" "IPv4: macvlan_2->macvlan_2" +- check_connection "${m2_ns}" "${m1_ip6}" "IPv6: macvlan_2->macvlan_2" +- +- ip -n ${c_ns} neigh flush dev eth0 +-} +- +-trap cleanup EXIT +- +-setup_prepare +-ip netns add ${m1_ns} +-ip netns add ${m2_ns} +- +-modes="active-backup balance-tlb balance-alb" +- +-for mode in $modes; do +- macvlan_over_bond "mode $mode" +-done +- +-exit $EXIT_STATUS +diff --git a/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +new file mode 100755 +index 0000000000000..c4711272fe45d +--- /dev/null ++++ b/tools/testing/selftests/drivers/net/bonding/bond_macvlan_ipvlan.sh +@@ -0,0 +1,96 @@ ++#!/bin/bash ++# SPDX-License-Identifier: GPL-2.0 ++# ++# Test macvlan/ipvlan over bond ++ ++lib_dir=$(dirname "$0") ++source ${lib_dir}/bond_topo_2d1c.sh ++ ++xvlan1_ns="xvlan1-$(mktemp -u XXXXXX)" ++xvlan2_ns="xvlan2-$(mktemp -u XXXXXX)" ++xvlan1_ip4="192.0.2.11" ++xvlan1_ip6="2001:db8::11" ++xvlan2_ip4="192.0.2.12" ++xvlan2_ip6="2001:db8::12" ++ ++cleanup() ++{ ++ client_destroy ++ server_destroy ++ gateway_destroy ++ ++ ip netns del ${xvlan1_ns} ++ ip netns del ${xvlan2_ns} ++} ++ ++check_connection() ++{ ++ local ns=${1} ++ local target=${2} ++ local message=${3} ++ RET=0 ++ ++ ip netns exec ${ns} ping ${target} -c 4 -i 0.1 &>/dev/null ++ check_err $? "ping failed" ++ log_test "${bond_mode}/${xvlan_type}_${xvlan_mode}: ${message}" ++} ++ ++xvlan_over_bond() ++{ ++ local param="$1" ++ local xvlan_type="$2" ++ local xvlan_mode="$3" ++ RET=0 ++ ++ # setup new bond mode ++ bond_reset "${param}" ++ ++ ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} ++ ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan1_ns} ++ ip -n ${xvlan1_ns} link set dev ${xvlan_type}0 up ++ ip -n ${xvlan1_ns} addr add ${xvlan1_ip4}/24 dev ${xvlan_type}0 ++ ip -n ${xvlan1_ns} addr add ${xvlan1_ip6}/24 dev ${xvlan_type}0 ++ ++ ip -n ${s_ns} link add link bond0 name ${xvlan_type}0 type ${xvlan_type} mode ${xvlan_mode} ++ ip -n ${s_ns} link set ${xvlan_type}0 netns ${xvlan2_ns} ++ ip -n ${xvlan2_ns} link set dev ${xvlan_type}0 up ++ ip -n ${xvlan2_ns} addr add ${xvlan2_ip4}/24 dev ${xvlan_type}0 ++ ip -n ${xvlan2_ns} addr add ${xvlan2_ip6}/24 dev ${xvlan_type}0 ++ ++ sleep 2 ++ ++ check_connection "${c_ns}" "${s_ip4}" "IPv4: client->server" ++ check_connection "${c_ns}" "${s_ip6}" "IPv6: client->server" ++ check_connection "${c_ns}" "${xvlan1_ip4}" "IPv4: client->${xvlan_type}_1" ++ check_connection "${c_ns}" "${xvlan1_ip6}" "IPv6: client->${xvlan_type}_1" ++ check_connection "${c_ns}" "${xvlan2_ip4}" "IPv4: client->${xvlan_type}_2" ++ check_connection "${c_ns}" "${xvlan2_ip6}" "IPv6: client->${xvlan_type}_2" ++ check_connection "${xvlan1_ns}" "${xvlan2_ip4}" "IPv4: ${xvlan_type}_1->${xvlan_type}_2" ++ check_connection "${xvlan1_ns}" "${xvlan2_ip6}" "IPv6: ${xvlan_type}_1->${xvlan_type}_2" ++ ++ check_connection "${s_ns}" "${c_ip4}" "IPv4: server->client" ++ check_connection "${s_ns}" "${c_ip6}" "IPv6: server->client" ++ check_connection "${xvlan1_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_1->client" ++ check_connection "${xvlan1_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_1->client" ++ check_connection "${xvlan2_ns}" "${c_ip4}" "IPv4: ${xvlan_type}_2->client" ++ check_connection "${xvlan2_ns}" "${c_ip6}" "IPv6: ${xvlan_type}_2->client" ++ check_connection "${xvlan2_ns}" "${xvlan1_ip4}" "IPv4: ${xvlan_type}_2->${xvlan_type}_1" ++ check_connection "${xvlan2_ns}" "${xvlan1_ip6}" "IPv6: ${xvlan_type}_2->${xvlan_type}_1" ++ ++ ip -n ${c_ns} neigh flush dev eth0 ++} ++ ++trap cleanup EXIT ++ ++setup_prepare ++ip netns add ${xvlan1_ns} ++ip netns add ${xvlan2_ns} ++ ++bond_modes="active-backup balance-tlb balance-alb" ++ ++for bond_mode in ${bond_modes}; do ++ xvlan_over_bond "mode ${bond_mode}" macvlan bridge ++ xvlan_over_bond "mode ${bond_mode}" ipvlan l2 ++done ++ ++exit $EXIT_STATUS +diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config +index 899d7fb6ea8e9..dad4e5fda4db3 100644 +--- a/tools/testing/selftests/drivers/net/bonding/config ++++ b/tools/testing/selftests/drivers/net/bonding/config +@@ -3,6 +3,7 @@ CONFIG_BRIDGE=y + CONFIG_DUMMY=y + CONFIG_IPV6=y + CONFIG_MACVLAN=y ++CONFIG_IPVLAN=y + CONFIG_NET_ACT_GACT=y + CONFIG_NET_CLS_FLOWER=y + CONFIG_NET_SCH_INGRESS=y +-- +2.51.0 + diff --git a/queue-6.6/selftests-bonding-add-missing-build-configs.patch b/queue-6.6/selftests-bonding-add-missing-build-configs.patch new file mode 100644 index 0000000000..a823f72ff0 --- /dev/null +++ b/queue-6.6/selftests-bonding-add-missing-build-configs.patch @@ -0,0 +1,36 @@ +From 8fe97633d95f6219d4cb246d8a7ccccc813002de Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 15 Jan 2024 18:02:01 -0800 +Subject: selftests: bonding: add missing build configs + +From: Jakub Kicinski + +[ Upstream commit 03fb8565c880d57952d9b4ba0b36468bae52b554 ] + +bonding tests also try to create bridge, veth and dummy +interfaces. These are not currently listed in config. + +Fixes: bbb774d921e2 ("net: Add tests for bonding and team address list management") +Fixes: c078290a2b76 ("selftests: include bonding tests into the kselftest infra") +Acked-by: Muhammad Usama Anjum +Link: https://lore.kernel.org/r/20240116020201.1883023-1-kuba@kernel.org +Signed-off-by: Jakub Kicinski +Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/bonding/config | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config +index 70638fa50b2cc..f85b16fc5128c 100644 +--- a/tools/testing/selftests/drivers/net/bonding/config ++++ b/tools/testing/selftests/drivers/net/bonding/config +@@ -1,2 +1,5 @@ + CONFIG_BONDING=y ++CONFIG_BRIDGE=y ++CONFIG_DUMMY=y + CONFIG_MACVLAN=y ++CONFIG_VETH=y +-- +2.51.0 + diff --git a/queue-6.6/selftests-bonding-add-more-missing-config-options.patch b/queue-6.6/selftests-bonding-add-more-missing-config-options.patch new file mode 100644 index 0000000000..03b219675d --- /dev/null +++ b/queue-6.6/selftests-bonding-add-more-missing-config-options.patch @@ -0,0 +1,47 @@ +From 871c1238b424ea2cbc3e1ee7ba65d37dc34286fa Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Jan 2024 10:49:26 -0500 +Subject: selftests: bonding: Add more missing config options + +From: Benjamin Poirier + +[ Upstream commit dd2d40acdbb2b9e6bcddd5424b0e00c1760ecf26 ] + +As a followup to commit 03fb8565c880 ("selftests: bonding: add missing +build configs"), add more networking-specific config options which are +needed for bonding tests. + +For testing, I used the minimal config generated by virtme-ng and I added +the options in the config file. All bonding tests passed. + +Fixes: bbb774d921e2 ("net: Add tests for bonding and team address list management") # for ipv6 +Fixes: 6cbe791c0f4e ("kselftest: bonding: add num_grat_arp test") # for tc options +Fixes: 222c94ec0ad4 ("selftests: bonding: add tests for ether type changes") # for nlmon +Suggested-by: Jakub Kicinski +Signed-off-by: Benjamin Poirier +Link: https://lore.kernel.org/r/20240116154926.202164-1-bpoirier@nvidia.com +Signed-off-by: Paolo Abeni +Stable-dep-of: 2c28ee720ad1 ("selftests: bonding: add delay before each xvlan_over_bond connectivity check") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/drivers/net/bonding/config | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/drivers/net/bonding/config b/tools/testing/selftests/drivers/net/bonding/config +index f85b16fc5128c..899d7fb6ea8e9 100644 +--- a/tools/testing/selftests/drivers/net/bonding/config ++++ b/tools/testing/selftests/drivers/net/bonding/config +@@ -1,5 +1,10 @@ + CONFIG_BONDING=y + CONFIG_BRIDGE=y + CONFIG_DUMMY=y ++CONFIG_IPV6=y + CONFIG_MACVLAN=y ++CONFIG_NET_ACT_GACT=y ++CONFIG_NET_CLS_FLOWER=y ++CONFIG_NET_SCH_INGRESS=y ++CONFIG_NLMON=y + CONFIG_VETH=y +-- +2.51.0 + diff --git a/queue-6.6/selftests-bpf-fix-failure-paths-in-send_signal-test.patch b/queue-6.6/selftests-bpf-fix-failure-paths-in-send_signal-test.patch new file mode 100644 index 0000000000..6e99a6ade7 --- /dev/null +++ b/queue-6.6/selftests-bpf-fix-failure-paths-in-send_signal-test.patch @@ -0,0 +1,46 @@ +From 02f79754cf98bc91e2f0d2aed329bb6fdaa67d4f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 09:11:53 -0800 +Subject: selftests/bpf: Fix failure paths in send_signal test + +From: Alexei Starovoitov + +[ Upstream commit c13339039891dbdfa6c1972f0483bd07f610b776 ] + +When test_send_signal_kern__open_and_load() fails parent closes the +pipe which cases ASSERT_EQ(read(pipe_p2c...)) to fail, but child +continues and enters infinite loop, while parent is stuck in wait(NULL). +Other error paths have similar issue, so kill the child before waiting on it. + +The bug was discovered while compiling all of selftests with -O1 instead of -O2 +which caused progs/test_send_signal_kern.c to fail to load. + +Fixes: ab8b7f0cb358 ("tools/bpf: Add self tests for bpf_send_signal_thread()") +Signed-off-by: Alexei Starovoitov +Signed-off-by: Andrii Nakryiko +Acked-by: Eduard Zingerman +Link: https://lore.kernel.org/bpf/20251113171153.2583-1-alexei.starovoitov@gmail.com +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/send_signal.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tools/testing/selftests/bpf/prog_tests/send_signal.c b/tools/testing/selftests/bpf/prog_tests/send_signal.c +index 9adcda7f1fedc..61c9035000149 100644 +--- a/tools/testing/selftests/bpf/prog_tests/send_signal.c ++++ b/tools/testing/selftests/bpf/prog_tests/send_signal.c +@@ -145,6 +145,11 @@ static void test_send_signal_common(struct perf_event_attr *attr, + skel_open_load_failure: + close(pipe_c2p[0]); + close(pipe_p2c[1]); ++ /* ++ * Child is either about to exit cleanly or stuck in case of errors. ++ * Nudge it to exit. ++ */ ++ kill(pid, SIGKILL); + wait(NULL); + } + +-- +2.51.0 + diff --git a/queue-6.6/selftests-bpf-improve-reliability-of-test_perf_branc.patch b/queue-6.6/selftests-bpf-improve-reliability-of-test_perf_branc.patch new file mode 100644 index 0000000000..d25a0f2710 --- /dev/null +++ b/queue-6.6/selftests-bpf-improve-reliability-of-test_perf_branc.patch @@ -0,0 +1,126 @@ +From 9cc163e6489d1cd5fed51167365d78c9801e088e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 19 Nov 2025 14:35:40 +0000 +Subject: selftests/bpf: Improve reliability of test_perf_branches_no_hw() + +From: Matt Bobrowski + +[ Upstream commit ae24fc8a16b0481ea8c5acbc66453c49ec0431c4 ] + +Currently, test_perf_branches_no_hw() relies on the busy loop within +test_perf_branches_common() being slow enough to allow at least one +perf event sample tick to occur before starting to tear down the +backing perf event BPF program. With a relatively small fixed +iteration count of 1,000,000, this is not guaranteed on modern fast +CPUs, resulting in the test run to subsequently fail with the +following: + +bpf_testmod.ko is already unloaded. +Loading bpf_testmod.ko... +Successfully loaded bpf_testmod.ko. +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_good_sample:PASS:output not valid 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_stack 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_global 0 nsec +check_good_sample:PASS:read_branches_size 0 nsec +test_perf_branches_no_hw:PASS:perf_event_open 0 nsec +test_perf_branches_common:PASS:test_perf_branches_load 0 nsec +test_perf_branches_common:PASS:attach_perf_event 0 nsec +test_perf_branches_common:PASS:set_affinity 0 nsec +check_bad_sample:FAIL:output not valid no valid sample from prog +Summary: 0/1 PASSED, 0 SKIPPED, 1 FAILED +Successfully unloaded bpf_testmod.ko. + +On a modern CPU (i.e. one with a 3.5 GHz clock rate), executing 1 +million increments of a volatile integer can take significantly less +than 1 millisecond. If the spin loop and detachment of the perf event +BPF program elapses before the first 1 ms sampling interval elapses, +the perf event will never end up firing. Fix this by bumping the loop +iteration counter a little within test_perf_branches_common(), along +with ensuring adding another loop termination condition which is +directly influenced by the backing perf event BPF program +executing. Notably, a concious decision was made to not adjust the +sample_freq value as that is just not a reliable way to go about +fixing the problem. It effectively still leaves the race window open. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Reviewed-by: Jiri Olsa +Link: https://lore.kernel.org/r/20251119143540.2911424-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + .../selftests/bpf/prog_tests/perf_branches.c | 16 ++++++++++++++-- + .../selftests/bpf/progs/test_perf_branches.c | 3 +++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index 06c7986131d96..0a7ef770c487c 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -15,6 +15,10 @@ static void check_good_sample(struct test_perf_branches *skel) + int pbe_size = sizeof(struct perf_branch_entry); + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -45,6 +49,10 @@ static void check_bad_sample(struct test_perf_branches *skel) + int written_stack = skel->bss->written_stack_out; + int duration = 0; + ++ if (CHECK(!skel->bss->run_cnt, "invalid run_cnt", ++ "checked sample validity before prog run")) ++ return; ++ + if (CHECK(!skel->bss->valid, "output not valid", + "no valid sample from prog")) + return; +@@ -83,8 +91,12 @@ static void test_perf_branches_common(int perf_fd, + err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set); + if (CHECK(err, "set_affinity", "cpu #0, err %d\n", err)) + goto out_destroy; +- /* spin the loop for a while (random high number) */ +- for (i = 0; i < 1000000; ++i) ++ ++ /* Spin the loop for a while by using a high iteration count, and by ++ * checking whether the specific run count marker has been explicitly ++ * incremented at least once by the backing perf_event BPF program. ++ */ ++ for (i = 0; i < 100000000 && !*(volatile int *)&skel->bss->run_cnt; ++i) + ++j; + + test_perf_branches__detach(skel); +diff --git a/tools/testing/selftests/bpf/progs/test_perf_branches.c b/tools/testing/selftests/bpf/progs/test_perf_branches.c +index a1ccc831c882f..05ac9410cd68c 100644 +--- a/tools/testing/selftests/bpf/progs/test_perf_branches.c ++++ b/tools/testing/selftests/bpf/progs/test_perf_branches.c +@@ -8,6 +8,7 @@ + #include + + int valid = 0; ++int run_cnt = 0; + int required_size_out = 0; + int written_stack_out = 0; + int written_global_out = 0; +@@ -24,6 +25,8 @@ int perf_branches(void *ctx) + __u64 entries[4 * 3] = {0}; + int required_size, written_stack, written_global; + ++ ++run_cnt; ++ + /* write to stack */ + written_stack = bpf_read_branch_records(ctx, entries, sizeof(entries), 0); + /* ignore spurious events */ +-- +2.51.0 + diff --git a/queue-6.6/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch b/queue-6.6/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch new file mode 100644 index 0000000000..aad694b0be --- /dev/null +++ b/queue-6.6/selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch @@ -0,0 +1,52 @@ +From 4f0f2cab8d02f6f920416adaa5da95fd1a18e6f6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 14:20:59 +0000 +Subject: selftests/bpf: skip test_perf_branches_hw() on unsupported platforms + +From: Matt Bobrowski + +[ Upstream commit 27746aaf1b20172f0859546c4a3e82eca459f680 ] + +Gracefully skip the test_perf_branches_hw subtest on platforms that +do not support LBR or require specialized perf event attributes +to enable branch sampling. + +For example, AMD's Milan (Zen 3) supports BRS rather than traditional +LBR. This requires specific configurations (attr.type = PERF_TYPE_RAW, +attr.config = RETIRED_TAKEN_BRANCH_INSTRUCTIONS) that differ from the +generic setup used within this test. Notably, it also probably doesn't +hold much value to special case perf event configurations for selected +micro architectures. + +Fixes: 67306f84ca78c ("selftests/bpf: Add bpf_read_branch_records() selftest") +Signed-off-by: Matt Bobrowski +Acked-by: Song Liu +Link: https://lore.kernel.org/r/20251120142059.2836181-1-mattbobrowski@google.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/bpf/prog_tests/perf_branches.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/perf_branches.c b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +index bc24f83339d64..06c7986131d96 100644 +--- a/tools/testing/selftests/bpf/prog_tests/perf_branches.c ++++ b/tools/testing/selftests/bpf/prog_tests/perf_branches.c +@@ -116,11 +116,11 @@ static void test_perf_branches_hw(void) + pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC); + + /* +- * Some setups don't support branch records (virtual machines, !x86), +- * so skip test in this case. ++ * Some setups don't support LBR (virtual machines, !x86, AMD Milan Zen ++ * 3 which only supports BRS), so skip test in this case. + */ + if (pfd < 0) { +- if (errno == ENOENT || errno == EOPNOTSUPP) { ++ if (errno == ENOENT || errno == EOPNOTSUPP || errno == EINVAL) { + printf("%s:SKIP:no PERF_SAMPLE_BRANCH_STACK\n", + __func__); + test__skip(); +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index d2fd2ae3d7..0e92919ea1 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -44,3 +44,219 @@ comedi-check-device-s-attached-status-in-compat-ioctls.patch staging-rtl8723bs-fix-out-of-bounds-read-in-rtw_get_ie-parser.patch staging-rtl8723bs-fix-stack-buffer-overflow-in-onassocreq-ie-parsing.patch staging-rtl8723bs-fix-out-of-bounds-read-in-onbeacon-esr-ie-parsing.patch +smack-fix-bug-unprivileged-task-can-create-labels.patch +gpu-host1x-fix-race-in-syncpt-alloc-free.patch +drm-panel-visionox-rm69299-don-t-clear-all-mode-flag.patch +drm-vgem-fence-fix-potential-deadlock-on-release.patch +usb-fix-descriptor-count-when-handling-invalid-mbim-.patch +clk-renesas-cpg-mssr-add-missing-1ms-delay-into-rese.patch +clk-renesas-rzg2l-simplify-the-logic-in-rzg2l_mod_cl.patch +clk-renesas-rzg2l-remove-critical-area.patch +clk-renesas-rzg2l-use-x-format-specifier-to-print-cl.patch +clk-renesas-use-str_on_off-helper.patch +clk-renesas-pass-sub-struct-of-cpg_mssr_priv-to-cpg_.patch +clk-renesas-cpg-mssr-read-back-reset-registers-to-as.patch +hid-logitech-hidpp-do-not-assume-fap-in-hidpp_send_m.patch +objtool-fix-standalone-hacks-jump_label.patch +objtool-fix-weak-symbol-detection.patch +sched-fair-forfeit-vruntime-on-yield.patch +irqchip-irq-bcm7038-l1-fix-section-mismatch.patch +irqchip-irq-bcm7120-l2-fix-section-mismatch.patch +irqchip-irq-brcmstb-l2-fix-section-mismatch.patch +irqchip-imx-mu-msi-fix-section-mismatch.patch +irqchip-qcom-irq-combiner-fix-section-mismatch.patch +crypto-authenc-correctly-pass-einprogress-back-up-to.patch +ntfs3-fix-uninit-memory-after-failed-mi_read-in-mi_f.patch +ntfs3-fix-uninit-buffer-allocated-by-__getname.patch +rculist-add-hlist_nulls_replace_rcu-and-hlist_nulls_.patch +inet-avoid-ehash-lookup-race-in-inet_ehash_insert.patch +iio-imu-st_lsm6dsx-fix-measurement-unit-for-odr-stru.patch +block-mq-deadline-remove-support-for-zone-write-lock.patch +block-mq-deadline-introduce-dd_start_request.patch +block-mq-deadline-switch-back-to-a-single-dispatch-l.patch +arm64-dts-freescale-imx8mp-venice-gw7905-2x-remove-d.patch +arm64-dts-imx8mm-venice-gw72xx-remove-unused-sdhc1-p.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-uart.patch +arm64-dts-imx8mp-venice-gw702x-remove-off-board-sdhc.patch +pci-rcar-gen2-drop-arm-dependency-from-pci_rcar_gen2.patch +uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch +clk-qcom-camcc-sm6350-specify-titan-gdsc-power-domai.patch +clk-qcom-camcc-sm6350-fix-pll-config-of-pll2.patch +crypto-asymmetric_keys-prevent-overflow-in-asymmetri.patch +crypto-hisilicon-qm-restore-original-qos-values.patch +wifi-ath11k-fix-peer-he-mcs-assignment.patch +s390-smp-fix-fallback-cpu-detection.patch +s390-ap-don-t-leak-debug-feature-files-if-ap-instruc.patch +arm64-dts-ti-k3-am62p-fix-memory-ranges-for-gpu.patch +firmware-imx-scu-irq-fix-of-node-leak-in.patch +arm64-dts-qcom-sdm845-oneplus-correct-gpio-used-for-.patch +phy-mscc-fix-ptp-for-vsc8574-and-vsc8572.patch +sctp-defer-sctp_dbg_objcnt_dec-to-sctp_destroy_sock.patch +rdma-rxe-fix-null-deref-on-srq-rq.queue-after-resize.patch +arm-dts-renesas-gose-remove-superfluous-port-propert.patch +arm-dts-renesas-r9a06g032-rzn1d400-db-drop-invalid-c.patch +revert-mtd-rawnand-marvell-fix-layouts.patch +mtd-nand-relax-ecc-parameter-validation-check.patch +mtd-rawnand-lpc32xx_slc-fix-gpio-descriptor-leak-on-.patch +task_work-fix-nmi-race-condition.patch +x86-dumpstack-prevent-kasan-false-positive-warnings-.patch +tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch +soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch +pinctrl-stm32-fix-hwspinlock-resource-leak-in-probe-.patch +i3c-master-inherit-dma-masks-and-parameters-from-par.patch +i3c-fix-refcount-inconsistency-in-i3c_master_registe.patch +i3c-master-svc-prevent-incomplete-ibi-transaction.patch +interconnect-qcom-msm8996-add-missing-link-to-slave_.patch +arm64-dts-qcom-msm8996-add-interconnect-paths-to-usb.patch +interconnect-debugfs-fix-incorrect-error-handling-fo.patch +perf-maps-add-maps__load_first.patch +perf-lock-contention-load-kernel-map-before-lookup.patch +perf-record-skip-synthesize-event-when-open-evsel-fa.patch +power-supply-cw2015-check-devm_delayed_work_autocanc.patch +power-supply-rt9467-return-error-on-failure-in-rt946.patch +power-supply-rt9467-prevent-using-uninitialized-loca.patch +power-supply-wm831x-check-wm831x_set_bits-return-val.patch +power-supply-apm_power-only-unset-own-apm_get_power_.patch +scsi-target-do-not-write-nul-characters-into-ascii-c.patch +fs-9p-don-t-open-remote-file-with-append-mode-when-w.patch +spi-tegra210-quad-fix-timeout-handling.patch +arm-dts-am335x-netcom-plus-2xx-add-missing-gpio-labe.patch +arm-dts-omap3-beagle-xm-correct-obsolete-twl4030-pow.patch +arm-dts-omap3-n900-correct-obsolete-twl4030-power-co.patch +x86-boot-fix-page-table-access-in-5-level-to-4-level.patch +efi-libstub-fix-page-table-access-in-5-level-to-4-le.patch +mfd-da9055-fix-missing-regmap_del_irq_chip-in-error-.patch +ext4-correct-the-checking-of-quota-files-before-movi.patch +perf-x86-intel-correct-large-pebs-flag-check.patch +regulator-core-disable-supply-if-enabling-main-regul.patch +nbd-defer-config-put-in-recv_work.patch +scsi-stex-fix-reboot_notifier-leak-in-probe-error-pa.patch +scsi-smartpqi-fix-device-resources-accessed-after-de.patch +staging-most-i2c-drop-explicit-initialization-of-str.patch +staging-most-remove-broken-i2c-driver.patch +dt-bindings-pci-amlogic-fix-the-register-name-of-the.patch +rdma-rtrs-server-fix-error-handling-in-get_or_create.patch +arm-dts-stm32-stm32mp157c-phycore-fix-stmpe811-touch.patch +ntfs3-init-run-lock-for-extend-inode.patch +scsi-ufs-core-fix-incorrect-buffer-duplication-in-uf.patch +cpufreq-amd-pstate-call-cppc_set_auto_sel-only-for-o.patch +powerpc-32-fix-unpaired-stwcx.-on-interrupt-exit.patch +macintosh-mac_hid-fix-race-condition-in-mac_hid_togg.patch +wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch +nbd-defer-config-unlock-in-nbd_genl_connect.patch +coresight-etm4x-correct-polling-idle-bit.patch +coresight-etm4x-extract-the-trace-unit-controlling.patch +coresight-etm4x-add-context-synchronization-before-e.patch +clk-renesas-r9a06g032-fix-memory-leak-in-error-path.patch +lib-vsprintf-check-pointer-before-dereferencing-in-t.patch +ocfs2-relax-bug-to-ocfs2_error-in-__ocfs2_move_exten.patch +acpi-property-fix-fwnode-refcount-leak-in-acpi_fwnod.patch +scsi-sim710-fix-resource-leak-by-adding-missing-iopo.patch +leds-netxbig-fix-gpio-descriptor-leak-in-error-paths.patch +bpf-free-special-fields-when-update-lru_-percpu_hash.patch +pci-keystone-exit-ks_pcie_probe-for-invalid-mode.patch +arm64-dts-rockchip-move-the-eeprom-to-correct-i2c-bu.patch +arm64-dts-rockchip-add-eeprom-vcc-supply-for-radxa-r.patch +ps3disk-use-memcpy_-from-to-_bvec-index.patch +bpf-handle-return-value-of-ftrace_set_filter_ip-in-r.patch +selftests-bpf-fix-failure-paths-in-send_signal-test.patch +bpf-check-skb-transport_header-is-set-in-bpf_skb_che.patch +watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch +watchdog-starfive-fix-resource-leak-in-probe-error-p.patch +tracefs-fix-a-leak-in-eventfs_create_events_dir.patch +nfsd-blocklayout-fix-minlength-check-in-proc_layoutg.patch +drm-msm-a2xx-stop-over-complaining-about-the-legacy-.patch +wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch +bpf-improve-program-stats-run-time-calculation.patch +bpf-fix-invalid-prog-stats-access-when-update_effect.patch +powerpc-64s-hash-restrict-stress_hpt_struct-memblock.patch +powerpc-64s-ptdump-fix-kernel_hash_pagetable-dump-fo.patch +fs-ntfs3-out1-also-needs-to-put-mi.patch +fs-ntfs3-prevent-memory-leaks-in-add-sub-record.patch +drm-mediatek-fix-ccorr-mtk_ctm_s31_32_to_s1_n-functi.patch +net-ipv6-remove-expired-routes-with-a-separated-list.patch +ipv6-clear-ra-flags-when-adding-a-static-route.patch +perf-arm-spe-extend-branch-operations.patch +perf-arm_spe-fix-memset-subclass-in-operation.patch +pwm-bcm2835-make-sure-the-channel-is-enabled-after-p.patch +scsi-qla2xxx-fix-improper-freeing-of-purex-item.patch +wifi-mac80211-remove-rx_drop_unusable.patch +wifi-mac80211-fix-cmac-functions-not-handling-errors.patch +mfd-mt6397-irq-fix-missing-irq_domain_remove-in-erro.patch +mfd-mt6358-irq-fix-missing-irq_domain_remove-in-erro.patch +phy-renesas-rcar-gen3-usb2-fix-an-error-handling-pat.patch +net-phy-adin1100-fix-software-power-down-ready-condi.patch +cpuset-treat-cpusets-in-attaching-as-populated.patch +wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch +ima-handle-error-code-returned-by-ima_filter_rule_ma.patch +usb-chaoskey-fix-locking-for-o_nonblock.patch +usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch +usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch +usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch +usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch +selftests-bpf-skip-test_perf_branches_hw-on-unsuppor.patch +selftests-bpf-improve-reliability-of-test_perf_branc.patch +crypto-starfive-correctly-handle-return-of-sg_nents_.patch +crypto-ccree-correctly-handle-return-of-sg_nents_for.patch +risc-v-kvm-fix-guest-page-fault-within-hlv-instructi.patch +rdma-bnxt_re-fix-the-inline-size-for-genp7-devices.patch +mt76-mt7615-fix-memory-leak-in-mt7615_mcu_wtbl_sta_a.patch +firmware-stratix10-svc-fix-make-htmldocs-warning-for.patch +staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch +btrfs-fix-leaf-leak-in-an-error-path-in-btrfs_del_it.patch +pci-dwc-fix-wrong-port_logic_ltssm_state_mask-defini.patch +drm-nouveau-restrict-the-flush-page-to-a-32-bit-addr.patch +iomap-factor-out-a-iomap_dio_done-helper.patch +iomap-always-run-error-completions-in-user-context.patch +wifi-ieee80211-correct-fils-status-codes.patch +backlight-led-bl-add-devlink-to-supplier-leds.patch +backlight-lp855x-fix-lp855x.h-kernel-doc-warnings.patch +iommu-arm-smmu-qcom-enable-use-of-all-smr-groups-whe.patch +rdma-irdma-fix-data-race-in-irdma_sc_ccq_arm.patch +rdma-irdma-fix-data-race-in-irdma_free_pble.patch +rdma-irdma-add-support-to-re-register-a-memory-regio.patch +rdma-irdma-do-not-directly-rely-on-ib_pd_unsafe_glob.patch +asoc-fsl_xcvr-clear-the-channel-status-control-memor.patch +kernfs-fix-memory-leak-of-kernfs_iattrs-in-__kernfs_.patch +drm-amd-display-fix-logical-vs-bitwise-bug-in-get_em.patch +hwmon-sy7636a-fix-regulator_enable-resource-leak-on-.patch +acpi-processor_core-fix-map_x2apic_id-for-amd-pstate.patch +ublk-make-sure-io-cmd-handled-in-submitter-task-cont.patch +ublk-complete-command-synchronously-on-error.patch +ublk-prevent-invalid-access-with-debug.patch +ext4-remove-unused-return-value-of-__mb_check_buddy.patch +ext4-improve-integrity-checking-in-__mb_check_buddy-.patch +virtio_vdpa-fix-misleading-return-in-void-function.patch +virtio-fix-typo-in-virtio_device_ready-comment.patch +virtio-fix-whitespace-in-virtio_config_ops.patch +virtio-fix-virtqueue_set_affinity-docs.patch +vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch +asoc-intel-catpt-fix-error-path-in-hw_params.patch +arm-dts-samsung-universal_c210-turn-off-sdio-wlan-ch.patch +arm-dts-samsung-exynos4210-i9100-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4210-trats-turn-off-sdio-wlan-.patch +arm-dts-samsung-exynos4412-midas-turn-off-sdio-wlan-.patch +regulator-core-protect-regulator_supply_alias_list-w.patch +resource-reuse-for_each_resource-macro.patch +resource-replace-open-coded-resource_intersection.patch +resource-introduce-is_type_match-helper-and-use-it.patch +reinstate-resource-avoid-unnecessary-lookups-in-find.patch +netfilter-flowtable-check-for-maximum-number-of-enca.patch +netfilter-nf_conncount-rework-api-to-use-sk_buff-dir.patch +netfilter-nft_connlimit-update-the-count-if-add-was-.patch +net-stmmac-fix-rx-limit-check-in-stmmac_rx_zc.patch +mtd-rawnand-renesas-handle-devm_pm_runtime_enable-er.patch +selftests-bonding-add-missing-build-configs.patch +selftests-bonding-add-more-missing-config-options.patch +selftests-bonding-add-ipvlan-over-bond-testing.patch +selftests-bonding-add-delay-before-each-xvlan_over_b.patch +mtd-lpddr_cmds-fix-signed-shifts-in-lpddr_cmds.patch +remoteproc-qcom_q6v5_wcss-fix-parsing-of-qcom-halt-r.patch +md-raid5-fix-io-hang-when-array-is-broken-with-io-in.patch +clk-keystone-fix-compile-testing.patch +net-sched-sch_cake-fix-incorrect-qlen-reduction-in-c.patch +perf-tools-fix-split-kallsyms-dso-counting.patch +pinctrl-single-fix-pin_config_bias_disable-handling.patch +pinctrl-single-fix-incorrect-type-for-error-return-v.patch +fbdev-ssd1307fb-fix-potential-page-leak-in-ssd1307fb.patch +9p-fix-cache-debug-options-printing-in-v9fs_show_opt.patch diff --git a/queue-6.6/smack-fix-bug-unprivileged-task-can-create-labels.patch b/queue-6.6/smack-fix-bug-unprivileged-task-can-create-labels.patch new file mode 100644 index 0000000000..40bc9bd53e --- /dev/null +++ b/queue-6.6/smack-fix-bug-unprivileged-task-can-create-labels.patch @@ -0,0 +1,101 @@ +From 08edb5bc0a6d9d3d88de1e7117ce0e8044e81f60 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 17 Jun 2025 00:32:16 +0300 +Subject: smack: fix bug: unprivileged task can create labels + +From: Konstantin Andreev + +[ Upstream commit c147e13ea7fe9f118f8c9ba5e96cbd644b00d6b3 ] + +If an unprivileged task is allowed to relabel itself +(/smack/relabel-self is not empty), +it can freely create new labels by writing their +names into own /proc/PID/attr/smack/current + +This occurs because do_setattr() imports +the provided label in advance, +before checking "relabel-self" list. + +This change ensures that the "relabel-self" list +is checked before importing the label. + +Fixes: 38416e53936e ("Smack: limited capability for changing process label") +Signed-off-by: Konstantin Andreev +Signed-off-by: Casey Schaufler +Signed-off-by: Sasha Levin +--- + security/smack/smack_lsm.c | 41 +++++++++++++++++++++++++------------- + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c +index d272cf8160d53..8d38f4a813171 100644 +--- a/security/smack/smack_lsm.c ++++ b/security/smack/smack_lsm.c +@@ -3687,8 +3687,8 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + struct task_smack *tsp = smack_cred(current_cred()); + struct cred *new; + struct smack_known *skp; +- struct smack_known_list_elem *sklep; +- int rc; ++ char *labelstr; ++ int rc = 0; + + if (!smack_privileged(CAP_MAC_ADMIN) && list_empty(&tsp->smk_relabel)) + return -EPERM; +@@ -3699,28 +3699,41 @@ static int smack_setprocattr(const char *name, void *value, size_t size) + if (strcmp(name, "current") != 0) + return -EINVAL; + +- skp = smk_import_entry(value, size); +- if (IS_ERR(skp)) +- return PTR_ERR(skp); ++ labelstr = smk_parse_smack(value, size); ++ if (IS_ERR(labelstr)) ++ return PTR_ERR(labelstr); + + /* + * No process is ever allowed the web ("@") label + * and the star ("*") label. + */ +- if (skp == &smack_known_web || skp == &smack_known_star) +- return -EINVAL; ++ if (labelstr[1] == '\0' /* '@', '*' */) { ++ const char c = labelstr[0]; ++ ++ if (c == *smack_known_web.smk_known || ++ c == *smack_known_star.smk_known) { ++ rc = -EPERM; ++ goto free_labelstr; ++ } ++ } + + if (!smack_privileged(CAP_MAC_ADMIN)) { +- rc = -EPERM; ++ const struct smack_known_list_elem *sklep; + list_for_each_entry(sklep, &tsp->smk_relabel, list) +- if (sklep->smk_label == skp) { +- rc = 0; +- break; +- } +- if (rc) +- return rc; ++ if (strcmp(sklep->smk_label->smk_known, labelstr) == 0) ++ goto free_labelstr; ++ rc = -EPERM; + } + ++free_labelstr: ++ kfree(labelstr); ++ if (rc) ++ return -EPERM; ++ ++ skp = smk_import_entry(value, size); ++ if (IS_ERR(skp)) ++ return PTR_ERR(skp); ++ + new = prepare_creds(); + if (new == NULL) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.6/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch b/queue-6.6/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch new file mode 100644 index 0000000000..5cc637003b --- /dev/null +++ b/queue-6.6/soc-qcom-smem-fix-hwspinlock-resource-leak-in-probe-.patch @@ -0,0 +1,51 @@ +From e46d570b1967705343cebe386e140e981f11989d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:27:33 +0800 +Subject: soc: qcom: smem: fix hwspinlock resource leak in probe error paths + +From: Haotian Zhang + +[ Upstream commit dc5db35073a19f6d3c30bea367b551c1a784ef8f ] + +The hwspinlock acquired via hwspin_lock_request_specific() is not +released on several error paths. This results in resource leakage +when probe fails. + +Switch to devm_hwspin_lock_request_specific() to automatically +handle cleanup on probe failure. Remove the manual hwspin_lock_free() +in qcom_smem_remove() as devm handles it automatically. + +Fixes: 20bb6c9de1b7 ("soc: qcom: smem: map only partitions used by local HOST") +Signed-off-by: Haotian Zhang +Reviewed-by: Konrad Dybcio +Link: https://lore.kernel.org/r/20251029022733.255-1-vulab@iscas.ac.cn +Signed-off-by: Bjorn Andersson +Signed-off-by: Sasha Levin +--- + drivers/soc/qcom/smem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c +index aead7dd482ea3..5217ff0a434f5 100644 +--- a/drivers/soc/qcom/smem.c ++++ b/drivers/soc/qcom/smem.c +@@ -1164,7 +1164,7 @@ static int qcom_smem_probe(struct platform_device *pdev) + return hwlock_id; + } + +- smem->hwlock = hwspin_lock_request_specific(hwlock_id); ++ smem->hwlock = devm_hwspin_lock_request_specific(&pdev->dev, hwlock_id); + if (!smem->hwlock) + return -ENXIO; + +@@ -1217,7 +1217,6 @@ static int qcom_smem_remove(struct platform_device *pdev) + { + platform_device_unregister(__smem->socinfo); + +- hwspin_lock_free(__smem->hwlock); + __smem = NULL; + + return 0; +-- +2.51.0 + diff --git a/queue-6.6/spi-tegra210-quad-fix-timeout-handling.patch b/queue-6.6/spi-tegra210-quad-fix-timeout-handling.patch new file mode 100644 index 0000000000..c2ef8e1f23 --- /dev/null +++ b/queue-6.6/spi-tegra210-quad-fix-timeout-handling.patch @@ -0,0 +1,117 @@ +From 26683bbd8e5ca26408247228f80118869dcb51ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 15:57:01 +0000 +Subject: spi: tegra210-quad: Fix timeout handling + +From: Vishwaroop A + +[ Upstream commit b4e002d8a7cee3b1d70efad0e222567f92a73000 ] + +When the CPU that the QSPI interrupt handler runs on (typically CPU 0) +is excessively busy, it can lead to rare cases of the IRQ thread not +running before the transfer timeout is reached. + +While handling the timeouts, any pending transfers are cleaned up and +the message that they correspond to is marked as failed, which leaves +the curr_xfer field pointing at stale memory. + +To avoid this, clear curr_xfer to NULL upon timeout and check for this +condition when the IRQ thread is finally run. + +While at it, also make sure to clear interrupts on failure so that new +interrupts can be run. + +A better, more involved, fix would move the interrupt clearing into a +hard IRQ handler. Ideally we would also want to signal that the IRQ +thread no longer needs to be run after the timeout is hit to avoid the +extra check for a valid transfer. + +Fixes: 921fc1838fb0 ("spi: tegra210-quad: Add support for Tegra210 QSPI controller") +Signed-off-by: Thierry Reding +Signed-off-by: Vishwaroop A +Link: https://patch.msgid.link/20251028155703.4151791-2-va@nvidia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-tegra210-quad.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c +index e9afebd724237..d9a487274b530 100644 +--- a/drivers/spi/spi-tegra210-quad.c ++++ b/drivers/spi/spi-tegra210-quad.c +@@ -999,8 +999,10 @@ static void tegra_qspi_handle_error(struct tegra_qspi *tqspi) + dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg); + tegra_qspi_dump_regs(tqspi); + tegra_qspi_flush_fifos(tqspi, true); +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + } + + static void tegra_qspi_transfer_end(struct spi_device *spi) +@@ -1145,9 +1147,11 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + } + + /* Reset controller if timeout happens */ +- if (device_reset(tqspi->dev) < 0) ++ if (device_reset(tqspi->dev) < 0) { + dev_warn_once(tqspi->dev, + "device reset failed\n"); ++ tegra_qspi_mask_clear_irq(tqspi); ++ } + ret = -EIO; + goto exit; + } +@@ -1169,11 +1173,13 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); + } ++ tqspi->curr_xfer = NULL; + transfer_phase++; + } + ret = 0; + + exit: ++ tqspi->curr_xfer = NULL; + msg->status = ret; + + return ret; +@@ -1257,6 +1263,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, + msg->actual_length += xfer->len + dummy_bytes; + + complete_xfer: ++ tqspi->curr_xfer = NULL; ++ + if (ret < 0) { + tegra_qspi_transfer_end(spi); + spi_transfer_delay_exec(xfer); +@@ -1353,6 +1361,7 @@ static irqreturn_t handle_cpu_based_xfer(struct tegra_qspi *tqspi) + tegra_qspi_calculate_curr_xfer_param(tqspi, t); + tegra_qspi_start_cpu_based_transfer(tqspi, t); + exit: ++ tqspi->curr_xfer = NULL; + spin_unlock_irqrestore(&tqspi->lock, flags); + return IRQ_HANDLED; + } +@@ -1436,6 +1445,15 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) + { + struct tegra_qspi *tqspi = context_data; + ++ /* ++ * Occasionally the IRQ thread takes a long time to wake up (usually ++ * when the CPU that it's running on is excessively busy) and we have ++ * already reached the timeout before and cleaned up the timed out ++ * transfer. Avoid any processing in that case and bail out early. ++ */ ++ if (!tqspi->curr_xfer) ++ return IRQ_NONE; ++ + tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) +-- +2.51.0 + diff --git a/queue-6.6/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch b/queue-6.6/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch new file mode 100644 index 0000000000..c5c98d389a --- /dev/null +++ b/queue-6.6/staging-fbtft-core-fix-potential-memory-leak-in-fbtf.patch @@ -0,0 +1,47 @@ +From 0b784f559f92829f8dc530380c3748e6a8f43955 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Nov 2025 20:22:07 +0100 +Subject: staging: fbtft: core: fix potential memory leak in + fbtft_probe_common() + +From: Jianglei Nie + +[ Upstream commit 47d3949a9b04cbcb0e10abae30c2b53e98706e11 ] + +fbtft_probe_common() allocates a memory chunk for "info" with +fbtft_framebuffer_alloc(). When "display->buswidth == 0" is true, the +function returns without releasing the "info", which will lead to a +memory leak. + +Fix it by calling fbtft_framebuffer_release() when "display->buswidth +== 0" is true. + +Fixes: c296d5f9957c ("staging: fbtft: core support") +Signed-off-by: Jianglei Nie +Signed-off-by: Andy Shevchenko +Acked-by: Abdun Nihaal +Link: https://patch.msgid.link/20251112192235.2088654-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/fbtft/fbtft-core.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c +index dce721f440c5e..5dfe2d7a73e37 100644 +--- a/drivers/staging/fbtft/fbtft-core.c ++++ b/drivers/staging/fbtft/fbtft-core.c +@@ -1225,8 +1225,8 @@ int fbtft_probe_common(struct fbtft_display *display, + par->pdev = pdev; + + if (display->buswidth == 0) { +- dev_err(dev, "buswidth is not set\n"); +- return -EINVAL; ++ ret = dev_err_probe(dev, -EINVAL, "buswidth is not set\n"); ++ goto out_release; + } + + /* write register functions */ +-- +2.51.0 + diff --git a/queue-6.6/staging-most-i2c-drop-explicit-initialization-of-str.patch b/queue-6.6/staging-most-i2c-drop-explicit-initialization-of-str.patch new file mode 100644 index 0000000000..cb4ea962bd --- /dev/null +++ b/queue-6.6/staging-most-i2c-drop-explicit-initialization-of-str.patch @@ -0,0 +1,50 @@ +From fedde9aee270a0ab42a6b1e45aab17ae044167fe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 Sep 2024 17:34:33 +0200 +Subject: staging: most: i2c: Drop explicit initialization of struct + i2c_device_id::driver_data to 0 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit b5b7a2c92332b6f799e81f256aed6a93a0e037fd ] + +These drivers don't use the driver_data member of struct i2c_device_id, +so don't explicitly initialize this member. + +This prepares putting driver_data in an anonymous union which requires +either no initialization or named designators. But it's also a nice +cleanup on its own. + +While touching the initializer, also remove the comma after the sentinel +entry. + +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20240920153430.503212-15-u.kleine-koenig@baylibre.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: 495df2da6944 ("staging: most: remove broken i2c driver") +Signed-off-by: Sasha Levin +--- + drivers/staging/most/i2c/i2c.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c +index ce869280a056b..184b2dd11fc34 100644 +--- a/drivers/staging/most/i2c/i2c.c ++++ b/drivers/staging/most/i2c/i2c.c +@@ -352,8 +352,8 @@ static void i2c_remove(struct i2c_client *client) + } + + static const struct i2c_device_id i2c_id[] = { +- { "most_i2c", 0 }, +- { }, /* Terminating entry */ ++ { "most_i2c" }, ++ { } /* Terminating entry */ + }; + + MODULE_DEVICE_TABLE(i2c, i2c_id); +-- +2.51.0 + diff --git a/queue-6.6/staging-most-remove-broken-i2c-driver.patch b/queue-6.6/staging-most-remove-broken-i2c-driver.patch new file mode 100644 index 0000000000..3dfefdf624 --- /dev/null +++ b/queue-6.6/staging-most-remove-broken-i2c-driver.patch @@ -0,0 +1,467 @@ +From f432f12ce42c2f52cc1789a649e95ca50b04b218 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 29 Oct 2025 10:34:42 +0100 +Subject: staging: most: remove broken i2c driver + +From: Johan Hovold + +[ Upstream commit 495df2da6944477d282d5cc0c13174d06e25b310 ] + +The MOST I2C driver has been completely broken for five years without +anyone noticing so remove the driver from staging. + +Specifically, commit 723de0f9171e ("staging: most: remove device from +interface structure") started requiring drivers to set the interface +device pointer before registration, but the I2C driver was never updated +which results in a NULL pointer dereference if anyone ever tries to +probe it. + +Fixes: 723de0f9171e ("staging: most: remove device from interface structure") +Cc: Christian Gromm +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20251029093442.29256-1-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/staging/most/Kconfig | 2 - + drivers/staging/most/Makefile | 1 - + drivers/staging/most/i2c/Kconfig | 13 -- + drivers/staging/most/i2c/Makefile | 4 - + drivers/staging/most/i2c/i2c.c | 374 ------------------------------ + 5 files changed, 394 deletions(-) + delete mode 100644 drivers/staging/most/i2c/Kconfig + delete mode 100644 drivers/staging/most/i2c/Makefile + delete mode 100644 drivers/staging/most/i2c/i2c.c + +diff --git a/drivers/staging/most/Kconfig b/drivers/staging/most/Kconfig +index 6f420cbcdcfff..e89658df6f124 100644 +--- a/drivers/staging/most/Kconfig ++++ b/drivers/staging/most/Kconfig +@@ -24,6 +24,4 @@ source "drivers/staging/most/video/Kconfig" + + source "drivers/staging/most/dim2/Kconfig" + +-source "drivers/staging/most/i2c/Kconfig" +- + endif +diff --git a/drivers/staging/most/Makefile b/drivers/staging/most/Makefile +index 8b3fc5a7af514..e45084df7803a 100644 +--- a/drivers/staging/most/Makefile ++++ b/drivers/staging/most/Makefile +@@ -3,4 +3,3 @@ + obj-$(CONFIG_MOST_NET) += net/ + obj-$(CONFIG_MOST_VIDEO) += video/ + obj-$(CONFIG_MOST_DIM2) += dim2/ +-obj-$(CONFIG_MOST_I2C) += i2c/ +diff --git a/drivers/staging/most/i2c/Kconfig b/drivers/staging/most/i2c/Kconfig +deleted file mode 100644 +index ff64283cbad18..0000000000000 +--- a/drivers/staging/most/i2c/Kconfig ++++ /dev/null +@@ -1,13 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-# +-# MOST I2C configuration +-# +- +-config MOST_I2C +- tristate "I2C" +- depends on I2C +- help +- Say Y here if you want to connect via I2C to network transceiver. +- +- To compile this driver as a module, choose M here: the +- module will be called most_i2c. +diff --git a/drivers/staging/most/i2c/Makefile b/drivers/staging/most/i2c/Makefile +deleted file mode 100644 +index 71099dd0f85b9..0000000000000 +--- a/drivers/staging/most/i2c/Makefile ++++ /dev/null +@@ -1,4 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0 +-obj-$(CONFIG_MOST_I2C) += most_i2c.o +- +-most_i2c-objs := i2c.o +diff --git a/drivers/staging/most/i2c/i2c.c b/drivers/staging/most/i2c/i2c.c +deleted file mode 100644 +index 184b2dd11fc34..0000000000000 +--- a/drivers/staging/most/i2c/i2c.c ++++ /dev/null +@@ -1,374 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0 +-/* +- * i2c.c - Hardware Dependent Module for I2C Interface +- * +- * Copyright (C) 2013-2015, Microchip Technology Germany II GmbH & Co. KG +- */ +- +-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-enum { CH_RX, CH_TX, NUM_CHANNELS }; +- +-#define MAX_BUFFERS_CONTROL 32 +-#define MAX_BUF_SIZE_CONTROL 256 +- +-/** +- * list_first_mbo - get the first mbo from a list +- * @ptr: the list head to take the mbo from. +- */ +-#define list_first_mbo(ptr) \ +- list_first_entry(ptr, struct mbo, list) +- +-static unsigned int polling_rate; +-module_param(polling_rate, uint, 0644); +-MODULE_PARM_DESC(polling_rate, "Polling rate [Hz]. Default = 0 (use IRQ)"); +- +-struct hdm_i2c { +- struct most_interface most_iface; +- struct most_channel_capability capabilities[NUM_CHANNELS]; +- struct i2c_client *client; +- struct rx { +- struct delayed_work dwork; +- struct list_head list; +- bool int_disabled; +- unsigned int delay; +- } rx; +- char name[64]; +-}; +- +-static inline struct hdm_i2c *to_hdm(struct most_interface *iface) +-{ +- return container_of(iface, struct hdm_i2c, most_iface); +-} +- +-static irqreturn_t most_irq_handler(int, void *); +-static void pending_rx_work(struct work_struct *); +- +-/** +- * configure_channel - called from MOST core to configure a channel +- * @most_iface: interface the channel belongs to +- * @ch_idx: channel to be configured +- * @channel_config: structure that holds the configuration information +- * +- * Return 0 on success, negative on failure. +- * +- * Receives configuration information from MOST core and initialize the +- * corresponding channel. +- */ +-static int configure_channel(struct most_interface *most_iface, +- int ch_idx, +- struct most_channel_config *channel_config) +-{ +- int ret; +- struct hdm_i2c *dev = to_hdm(most_iface); +- unsigned int delay, pr; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (channel_config->data_type != MOST_CH_CONTROL) { +- pr_err("bad data type for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction != dev->capabilities[ch_idx].direction) { +- pr_err("bad direction for channel %d\n", ch_idx); +- return -EPERM; +- } +- +- if (channel_config->direction == MOST_CH_RX) { +- if (!polling_rate) { +- if (dev->client->irq <= 0) { +- pr_err("bad irq: %d\n", dev->client->irq); +- return -ENOENT; +- } +- dev->rx.int_disabled = false; +- ret = request_irq(dev->client->irq, most_irq_handler, 0, +- dev->client->name, dev); +- if (ret) { +- pr_err("request_irq(%d) failed: %d\n", +- dev->client->irq, ret); +- return ret; +- } +- } else { +- delay = msecs_to_jiffies(MSEC_PER_SEC / polling_rate); +- dev->rx.delay = delay ? delay : 1; +- pr = MSEC_PER_SEC / jiffies_to_msecs(dev->rx.delay); +- pr_info("polling rate is %u Hz\n", pr); +- } +- } +- +- return 0; +-} +- +-/** +- * enqueue - called from MOST core to enqueue a buffer for data transfer +- * @most_iface: intended interface +- * @ch_idx: ID of the channel the buffer is intended for +- * @mbo: pointer to the buffer object +- * +- * Return 0 on success, negative on failure. +- * +- * Transmit the data over I2C if it is a "write" request or push the buffer into +- * list if it is an "read" request +- */ +-static int enqueue(struct most_interface *most_iface, +- int ch_idx, struct mbo *mbo) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- int ret; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- /* RX */ +- if (!polling_rate) +- disable_irq(dev->client->irq); +- cancel_delayed_work_sync(&dev->rx.dwork); +- list_add_tail(&mbo->list, &dev->rx.list); +- if (dev->rx.int_disabled || polling_rate) +- pending_rx_work(&dev->rx.dwork.work); +- if (!polling_rate) +- enable_irq(dev->client->irq); +- } else { +- /* TX */ +- ret = i2c_master_send(dev->client, mbo->virt_address, +- mbo->buffer_length); +- if (ret <= 0) { +- mbo->processed_length = 0; +- mbo->status = MBO_E_INVAL; +- } else { +- mbo->processed_length = mbo->buffer_length; +- mbo->status = MBO_SUCCESS; +- } +- mbo->complete(mbo); +- } +- +- return 0; +-} +- +-/** +- * poison_channel - called from MOST core to poison buffers of a channel +- * @most_iface: pointer to the interface the channel to be poisoned belongs to +- * @ch_idx: corresponding channel ID +- * +- * Return 0 on success, negative on failure. +- * +- * If channel direction is RX, complete the buffers in list with +- * status MBO_E_CLOSE +- */ +-static int poison_channel(struct most_interface *most_iface, +- int ch_idx) +-{ +- struct hdm_i2c *dev = to_hdm(most_iface); +- struct mbo *mbo; +- +- BUG_ON(ch_idx < 0 || ch_idx >= NUM_CHANNELS); +- +- if (ch_idx == CH_RX) { +- if (!polling_rate) +- free_irq(dev->client->irq, dev); +- cancel_delayed_work_sync(&dev->rx.dwork); +- +- while (!list_empty(&dev->rx.list)) { +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = 0; +- mbo->status = MBO_E_CLOSE; +- mbo->complete(mbo); +- } +- } +- +- return 0; +-} +- +-static void do_rx_work(struct hdm_i2c *dev) +-{ +- struct mbo *mbo; +- unsigned char msg[MAX_BUF_SIZE_CONTROL]; +- int ret; +- u16 pml, data_size; +- +- /* Read PML (2 bytes) */ +- ret = i2c_master_recv(dev->client, msg, 2); +- if (ret <= 0) { +- pr_err("Failed to receive PML\n"); +- return; +- } +- +- pml = (msg[0] << 8) | msg[1]; +- if (!pml) +- return; +- +- data_size = pml + 2; +- +- /* Read the whole message, including PML */ +- ret = i2c_master_recv(dev->client, msg, data_size); +- if (ret <= 0) { +- pr_err("Failed to receive a Port Message\n"); +- return; +- } +- +- mbo = list_first_mbo(&dev->rx.list); +- list_del(&mbo->list); +- +- mbo->processed_length = min(data_size, mbo->buffer_length); +- memcpy(mbo->virt_address, msg, mbo->processed_length); +- mbo->status = MBO_SUCCESS; +- mbo->complete(mbo); +-} +- +-/** +- * pending_rx_work - Read pending messages through I2C +- * @work: definition of this work item +- * +- * Invoked by the Interrupt Service Routine, most_irq_handler() +- */ +-static void pending_rx_work(struct work_struct *work) +-{ +- struct hdm_i2c *dev = container_of(work, struct hdm_i2c, rx.dwork.work); +- +- if (list_empty(&dev->rx.list)) +- return; +- +- do_rx_work(dev); +- +- if (polling_rate) { +- schedule_delayed_work(&dev->rx.dwork, dev->rx.delay); +- } else { +- dev->rx.int_disabled = false; +- enable_irq(dev->client->irq); +- } +-} +- +-/* +- * most_irq_handler - Interrupt Service Routine +- * @irq: irq number +- * @_dev: private data +- * +- * Schedules a delayed work +- * +- * By default the interrupt line behavior is Active Low. Once an interrupt is +- * generated by the device, until driver clears the interrupt (by reading +- * the PMP message), device keeps the interrupt line in low state. Since i2c +- * read is done in work queue, the interrupt line must be disabled temporarily +- * to avoid ISR being called repeatedly. Re-enable the interrupt in workqueue, +- * after reading the message. +- * +- * Note: If we use the interrupt line in Falling edge mode, there is a +- * possibility to miss interrupts when ISR is getting executed. +- * +- */ +-static irqreturn_t most_irq_handler(int irq, void *_dev) +-{ +- struct hdm_i2c *dev = _dev; +- +- disable_irq_nosync(irq); +- dev->rx.int_disabled = true; +- schedule_delayed_work(&dev->rx.dwork, 0); +- +- return IRQ_HANDLED; +-} +- +-/* +- * i2c_probe - i2c probe handler +- * @client: i2c client device structure +- * @id: i2c client device id +- * +- * Return 0 on success, negative on failure. +- * +- * Register the i2c client device as a MOST interface +- */ +-static int i2c_probe(struct i2c_client *client) +-{ +- struct hdm_i2c *dev; +- int ret, i; +- +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); +- if (!dev) +- return -ENOMEM; +- +- /* ID format: i2c--
*/ +- snprintf(dev->name, sizeof(dev->name), "i2c-%d-%04x", +- client->adapter->nr, client->addr); +- +- for (i = 0; i < NUM_CHANNELS; i++) { +- dev->capabilities[i].data_type = MOST_CH_CONTROL; +- dev->capabilities[i].num_buffers_packet = MAX_BUFFERS_CONTROL; +- dev->capabilities[i].buffer_size_packet = MAX_BUF_SIZE_CONTROL; +- } +- dev->capabilities[CH_RX].direction = MOST_CH_RX; +- dev->capabilities[CH_RX].name_suffix = "rx"; +- dev->capabilities[CH_TX].direction = MOST_CH_TX; +- dev->capabilities[CH_TX].name_suffix = "tx"; +- +- dev->most_iface.interface = ITYPE_I2C; +- dev->most_iface.description = dev->name; +- dev->most_iface.num_channels = NUM_CHANNELS; +- dev->most_iface.channel_vector = dev->capabilities; +- dev->most_iface.configure = configure_channel; +- dev->most_iface.enqueue = enqueue; +- dev->most_iface.poison_channel = poison_channel; +- +- INIT_LIST_HEAD(&dev->rx.list); +- +- INIT_DELAYED_WORK(&dev->rx.dwork, pending_rx_work); +- +- dev->client = client; +- i2c_set_clientdata(client, dev); +- +- ret = most_register_interface(&dev->most_iface); +- if (ret) { +- pr_err("Failed to register i2c as a MOST interface\n"); +- kfree(dev); +- return ret; +- } +- +- return 0; +-} +- +-/* +- * i2c_remove - i2c remove handler +- * @client: i2c client device structure +- * +- * Return 0 on success. +- * +- * Unregister the i2c client device as a MOST interface +- */ +-static void i2c_remove(struct i2c_client *client) +-{ +- struct hdm_i2c *dev = i2c_get_clientdata(client); +- +- most_deregister_interface(&dev->most_iface); +- kfree(dev); +-} +- +-static const struct i2c_device_id i2c_id[] = { +- { "most_i2c" }, +- { } /* Terminating entry */ +-}; +- +-MODULE_DEVICE_TABLE(i2c, i2c_id); +- +-static struct i2c_driver i2c_driver = { +- .driver = { +- .name = "hdm_i2c", +- }, +- .probe = i2c_probe, +- .remove = i2c_remove, +- .id_table = i2c_id, +-}; +- +-module_i2c_driver(i2c_driver); +- +-MODULE_AUTHOR("Andrey Shvetsov "); +-MODULE_DESCRIPTION("I2C Hardware Dependent Module"); +-MODULE_LICENSE("GPL"); +-- +2.51.0 + diff --git a/queue-6.6/task_work-fix-nmi-race-condition.patch b/queue-6.6/task_work-fix-nmi-race-condition.patch new file mode 100644 index 0000000000..a19828c8f2 --- /dev/null +++ b/queue-6.6/task_work-fix-nmi-race-condition.patch @@ -0,0 +1,62 @@ +From c701285092d010c85a961ddb51cb1fc870279616 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 15:47:00 +0200 +Subject: task_work: Fix NMI race condition + +From: Peter Zijlstra + +[ Upstream commit ef1ea98c8fffe227e5319215d84a53fa2a4bcebc ] + + __schedule() + // disable irqs + + task_work_add(current, work, TWA_NMI_CURRENT); + + // current = next; + // enable irqs + + task_work_set_notify_irq() + test_and_set_tsk_thread_flag(current, + TIF_NOTIFY_RESUME); // wrong task! + + // original task skips task work on its next return to user (or exit!) + +Fixes: 466e4d801cd4 ("task_work: Add TWA_NMI_CURRENT as an additional notify mode.") +Reported-by: Josh Poimboeuf +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Steven Rostedt (Google) +Link: https://patch.msgid.link/20250924080118.425949403@infradead.org +Signed-off-by: Sasha Levin +--- + kernel/task_work.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/kernel/task_work.c b/kernel/task_work.c +index c969f1f26be58..48ab6275e6e7e 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -9,7 +9,12 @@ static struct callback_head work_exited; /* all we need is ->next == NULL */ + #ifdef CONFIG_IRQ_WORK + static void task_work_set_notify_irq(struct irq_work *entry) + { +- test_and_set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); ++ /* ++ * no-op IPI ++ * ++ * TWA_NMI_CURRENT will already have set the TIF flag, all ++ * this interrupt does it tickle the return-to-user path. ++ */ + } + static DEFINE_PER_CPU(struct irq_work, irq_work_NMI_resume) = + IRQ_WORK_INIT_HARD(task_work_set_notify_irq); +@@ -98,6 +103,7 @@ int task_work_add(struct task_struct *task, struct callback_head *work, + break; + #ifdef CONFIG_IRQ_WORK + case TWA_NMI_CURRENT: ++ set_tsk_thread_flag(current, TIF_NOTIFY_RESUME); + irq_work_queue(this_cpu_ptr(&irq_work_NMI_resume)); + break; + #endif +-- +2.51.0 + diff --git a/queue-6.6/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch b/queue-6.6/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch new file mode 100644 index 0000000000..02cab78f06 --- /dev/null +++ b/queue-6.6/tools-nolibc-stdio-let-perror-work-when-nolibc_ignor.patch @@ -0,0 +1,43 @@ +From 5ad9f5d769f0cb4b34283fe9a5abf074d4877d0a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 24 Sep 2025 16:20:50 +0200 +Subject: tools/nolibc/stdio: let perror work when NOLIBC_IGNORE_ERRNO is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Benjamin Berg + +[ Upstream commit c485ca3aff2442adea4c08ceb5183e671ebed22a ] + +There is no errno variable when NOLIBC_IGNORE_ERRNO is defined. As such, +simply print the message with "unknown error" rather than the integer +value of errno. + +Fixes: acab7bcdb1bc ("tools/nolibc/stdio: add perror() to report the errno value") +Signed-off-by: Benjamin Berg +Signed-off-by: Thomas Weißschuh +Signed-off-by: Sasha Levin +--- + tools/include/nolibc/stdio.h | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h +index cae402c11e575..36952314eef6f 100644 +--- a/tools/include/nolibc/stdio.h ++++ b/tools/include/nolibc/stdio.h +@@ -352,7 +352,11 @@ int printf(const char *fmt, ...) + static __attribute__((unused)) + void perror(const char *msg) + { ++#ifdef NOLIBC_IGNORE_ERRNO ++ fprintf(stderr, "%s%sunknown error\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : ""); ++#else + fprintf(stderr, "%s%serrno=%d\n", (msg && *msg) ? msg : "", (msg && *msg) ? ": " : "", errno); ++#endif + } + + static __attribute__((unused)) +-- +2.51.0 + diff --git a/queue-6.6/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch b/queue-6.6/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch new file mode 100644 index 0000000000..12f2d7d868 --- /dev/null +++ b/queue-6.6/tracefs-fix-a-leak-in-eventfs_create_events_dir.patch @@ -0,0 +1,45 @@ +From c4cbbe911bef2362b922f22cbcfd153b7a3529c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 25 Oct 2025 18:13:48 -0400 +Subject: tracefs: fix a leak in eventfs_create_events_dir() + +From: Al Viro + +[ Upstream commit 798a401660a151633cb171738a72a8f1efb9b0b4 ] + +If we have LOCKDOWN_TRACEFS, the function bails out - *after* +having locked the parent directory and without bothering to +undo that. Just check it before tracefs_start_creating()... + +Fixes: e24709454c45 "tracefs/eventfs: Add missing lockdown checks" +Acked-by: Steven Rostedt (Google) +Signed-off-by: Al Viro +Signed-off-by: Sasha Levin +--- + fs/tracefs/event_inode.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/tracefs/event_inode.c b/fs/tracefs/event_inode.c +index 73a08db3b7a85..4190e61550449 100644 +--- a/fs/tracefs/event_inode.c ++++ b/fs/tracefs/event_inode.c +@@ -827,7 +827,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + const struct eventfs_entry *entries, + int size, void *data) + { +- struct dentry *dentry = tracefs_start_creating(name, parent); ++ struct dentry *dentry; + struct eventfs_root_inode *rei; + struct eventfs_inode *ei; + struct tracefs_inode *ti; +@@ -838,6 +838,7 @@ struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry + if (security_locked_down(LOCKDOWN_TRACEFS)) + return NULL; + ++ dentry = tracefs_start_creating(name, parent); + if (IS_ERR(dentry)) + return ERR_CAST(dentry); + +-- +2.51.0 + diff --git a/queue-6.6/ublk-complete-command-synchronously-on-error.patch b/queue-6.6/ublk-complete-command-synchronously-on-error.patch new file mode 100644 index 0000000000..44987f2c08 --- /dev/null +++ b/queue-6.6/ublk-complete-command-synchronously-on-error.patch @@ -0,0 +1,75 @@ +From 5df6646864caef2931e25351fc4aa64f7b47c6cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Feb 2025 14:24:55 -0700 +Subject: ublk: complete command synchronously on error + +From: Caleb Sander Mateos + +[ Upstream commit 603f9be21c1894e462416e3324962d6c9c2b95f8 ] + +In case of an error, ublk's ->uring_cmd() functions currently return +-EIOCBQUEUED and immediately call io_uring_cmd_done(). -EIOCBQUEUED and +io_uring_cmd_done() are intended for asynchronous completions. For +synchronous completions, the ->uring_cmd() function can just return the +negative return code directly. This skips io_uring_cmd_del_cancelable(), +and deferring the completion to task work. So return the error code +directly from __ublk_ch_uring_cmd() and ublk_ctrl_uring_cmd(). + +Update ublk_ch_uring_cmd_cb(), which currently ignores the return value +from __ublk_ch_uring_cmd(), to call io_uring_cmd_done() for synchronous +completions. + +Signed-off-by: Caleb Sander Mateos +Reviewed-by: Ming Lei +Reviewed-by: Keith Busch +Link: https://lore.kernel.org/r/20250225212456.2902549-1-csander@purestorage.com +Signed-off-by: Jens Axboe +Stable-dep-of: c6a45ee7607d ("ublk: prevent invalid access with DEBUG") +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index 6419f304fa5e2..88d566f0ffa64 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -1821,10 +1821,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + return -EIOCBQUEUED; + + out: +- io_uring_cmd_done(cmd, ret, 0, issue_flags); + pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", + __func__, cmd_op, tag, ret, io->flags); +- return -EIOCBQUEUED; ++ return ret; + } + + static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, +@@ -1880,7 +1879,10 @@ static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, + static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd, + unsigned int issue_flags) + { +- ublk_ch_uring_cmd_local(cmd, issue_flags); ++ int ret = ublk_ch_uring_cmd_local(cmd, issue_flags); ++ ++ if (ret != -EIOCBQUEUED) ++ io_uring_cmd_done(cmd, ret, 0, issue_flags); + } + + static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) +@@ -2948,10 +2950,9 @@ static int ublk_ctrl_uring_cmd(struct io_uring_cmd *cmd, + if (ub) + ublk_put_device(ub); + out: +- io_uring_cmd_done(cmd, ret, 0, issue_flags); + pr_devel("%s: cmd done ret %d cmd_op %x, dev id %d qid %d\n", + __func__, ret, cmd->cmd_op, header->dev_id, header->queue_id); +- return -EIOCBQUEUED; ++ return ret; + } + + static const struct file_operations ublk_ctl_fops = { +-- +2.51.0 + diff --git a/queue-6.6/ublk-make-sure-io-cmd-handled-in-submitter-task-cont.patch b/queue-6.6/ublk-make-sure-io-cmd-handled-in-submitter-task-cont.patch new file mode 100644 index 0000000000..6588a6180f --- /dev/null +++ b/queue-6.6/ublk-make-sure-io-cmd-handled-in-submitter-task-cont.patch @@ -0,0 +1,77 @@ +From 99507680a0a5fcf181a2a439993fc72fd4d7700d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 9 Oct 2023 17:33:17 +0800 +Subject: ublk: make sure io cmd handled in submitter task context + +From: Ming Lei + +[ Upstream commit 3421c7f68bba52281bbb38bc76c18dc03cb689e4 ] + +In well-done ublk server implementation, ublk io command won't be +linked into any link chain. Meantime they are always handled in no-wait +style, so basically io cmd is always handled in submitter task context. + +However, the server may set IOSQE_ASYNC, or io command is linked to one +chain mistakenly, then we may still run into io-wq context and +ctx->uring_lock isn't held. + +So in case of IO_URING_F_UNLOCKED, schedule this command by +io_uring_cmd_complete_in_task to force running it in submitter task. Then +ublk_ch_uring_cmd_local() is guaranteed to run with context uring_lock held, +and we needn't to worry about sync among submission code path any more. + +Signed-off-by: Ming Lei +Link: https://lore.kernel.org/r/20231009093324.957829-3-ming.lei@redhat.com +Signed-off-by: Jens Axboe +Stable-dep-of: c6a45ee7607d ("ublk: prevent invalid access with DEBUG") +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 22 +++++++++++++++++++++- + 1 file changed, 21 insertions(+), 1 deletion(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index ec6d7a08104d9..6419f304fa5e2 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -1857,7 +1857,8 @@ static inline struct request *__ublk_check_and_get_req(struct ublk_device *ub, + return NULL; + } + +-static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) ++static inline int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd, ++ unsigned int issue_flags) + { + /* + * Not necessary for async retry, but let's keep it simple and always +@@ -1871,9 +1872,28 @@ static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) + .addr = READ_ONCE(ub_src->addr) + }; + ++ WARN_ON_ONCE(issue_flags & IO_URING_F_UNLOCKED); ++ + return __ublk_ch_uring_cmd(cmd, issue_flags, &ub_cmd); + } + ++static void ublk_ch_uring_cmd_cb(struct io_uring_cmd *cmd, ++ unsigned int issue_flags) ++{ ++ ublk_ch_uring_cmd_local(cmd, issue_flags); ++} ++ ++static int ublk_ch_uring_cmd(struct io_uring_cmd *cmd, unsigned int issue_flags) ++{ ++ /* well-implemented server won't run into unlocked */ ++ if (unlikely(issue_flags & IO_URING_F_UNLOCKED)) { ++ io_uring_cmd_complete_in_task(cmd, ublk_ch_uring_cmd_cb); ++ return -EIOCBQUEUED; ++ } ++ ++ return ublk_ch_uring_cmd_local(cmd, issue_flags); ++} ++ + static inline bool ublk_check_ubuf_dir(const struct request *req, + int ubuf_dir) + { +-- +2.51.0 + diff --git a/queue-6.6/ublk-prevent-invalid-access-with-debug.patch b/queue-6.6/ublk-prevent-invalid-access-with-debug.patch new file mode 100644 index 0000000000..ee61390e61 --- /dev/null +++ b/queue-6.6/ublk-prevent-invalid-access-with-debug.patch @@ -0,0 +1,57 @@ +From 4a217388c856e78ca76733c603047a2bbb3e1f2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Nov 2025 12:48:35 +0000 +Subject: ublk: prevent invalid access with DEBUG + +From: Kevin Brodsky + +[ Upstream commit c6a45ee7607de3a350008630f4369b1b5ac80884 ] + +ublk_ch_uring_cmd_local() may jump to the out label before +initialising the io pointer. This will cause trouble if DEBUG is +defined, because the pr_devel() call dereferences io. Clang reports: + +drivers/block/ublk_drv.c:2403:6: error: variable 'io' is used uninitialized whenever 'if' condition is true [-Werror,-Wsometimes-uninitialized] + 2403 | if (tag >= ub->dev_info.queue_depth) + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +drivers/block/ublk_drv.c:2492:32: note: uninitialized use occurs here + 2492 | __func__, cmd_op, tag, ret, io->flags); + | + +Fix this by initialising io to NULL and checking it before +dereferencing it. + +Signed-off-by: Kevin Brodsky +Fixes: 71f28f3136af ("ublk_drv: add io_uring based userspace block driver") +Reviewed-by: Caleb Sander Mateos +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + drivers/block/ublk_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c +index 88d566f0ffa64..563b2a94d4c3c 100644 +--- a/drivers/block/ublk_drv.c ++++ b/drivers/block/ublk_drv.c +@@ -1709,7 +1709,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + { + struct ublk_device *ub = cmd->file->private_data; + struct ublk_queue *ubq; +- struct ublk_io *io; ++ struct ublk_io *io = NULL; + u32 cmd_op = cmd->cmd_op; + unsigned tag = ub_cmd->tag; + int ret = -EINVAL; +@@ -1822,7 +1822,7 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, + + out: + pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n", +- __func__, cmd_op, tag, ret, io->flags); ++ __func__, cmd_op, tag, ret, io ? io->flags : 0); + return ret; + } + +-- +2.51.0 + diff --git a/queue-6.6/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch b/queue-6.6/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch new file mode 100644 index 0000000000..2ad5a1a137 --- /dev/null +++ b/queue-6.6/uio-uio_fsl_elbc_gpcm-add-null-pointer-check-to-uio_.patch @@ -0,0 +1,50 @@ +From da57318eb27bb89cf573cb4261f2af158d4c3b36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 15 Oct 2025 14:40:20 +0800 +Subject: uio: uio_fsl_elbc_gpcm:: Add null pointer check to + uio_fsl_elbc_gpcm_probe + +From: Li Qiang + +[ Upstream commit d48fb15e6ad142e0577428a8c5028136e10c7b3d ] + +devm_kasprintf() returns a pointer to dynamically allocated memory +which can be NULL upon failure. + +Fixes: d57801c45f53e ("uio: uio_fsl_elbc_gpcm: use device-managed allocators") +Signed-off-by: Li Qiang +Link: https://patch.msgid.link/20251015064020.56589-1-liqiang01@kylinos.cn +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/uio/uio_fsl_elbc_gpcm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/uio/uio_fsl_elbc_gpcm.c b/drivers/uio/uio_fsl_elbc_gpcm.c +index 82dda799f327d..a433bc84313fa 100644 +--- a/drivers/uio/uio_fsl_elbc_gpcm.c ++++ b/drivers/uio/uio_fsl_elbc_gpcm.c +@@ -384,6 +384,11 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + + /* set all UIO data */ + info->mem[0].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%pOFn", node); ++ if (!info->mem[0].name) { ++ ret = -ENODEV; ++ goto out_err3; ++ } ++ + info->mem[0].addr = res.start; + info->mem[0].size = resource_size(&res); + info->mem[0].memtype = UIO_MEM_PHYS; +@@ -423,6 +428,8 @@ static int uio_fsl_elbc_gpcm_probe(struct platform_device *pdev) + out_err2: + if (priv->shutdown) + priv->shutdown(info, true); ++ ++out_err3: + iounmap(info->mem[0].internal_addr); + return ret; + } +-- +2.51.0 + diff --git a/queue-6.6/usb-chaoskey-fix-locking-for-o_nonblock.patch b/queue-6.6/usb-chaoskey-fix-locking-for-o_nonblock.patch new file mode 100644 index 0000000000..c3d9630c77 --- /dev/null +++ b/queue-6.6/usb-chaoskey-fix-locking-for-o_nonblock.patch @@ -0,0 +1,51 @@ +From de83e47c98bda0b7e6ca3562b52e33b987c3f75d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 30 Oct 2025 10:39:06 +0100 +Subject: usb: chaoskey: fix locking for O_NONBLOCK + +From: Oliver Neukum + +[ Upstream commit a2fa8a12e6bc9d89c0505b8dd7ae38ec173d25de ] + +A failure to take a lock with O_NONBLOCK needs to result +in -EAGAIN. Change it. + +Fixes: 66e3e591891da ("usb: Add driver for Altus Metrum ChaosKey device (v2)") +Signed-off-by: Oliver Neukum +Link: https://patch.msgid.link/20251030093918.2248104-1-oneukum@suse.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/misc/chaoskey.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/usb/misc/chaoskey.c b/drivers/usb/misc/chaoskey.c +index 225863321dc47..45cff32656c6e 100644 +--- a/drivers/usb/misc/chaoskey.c ++++ b/drivers/usb/misc/chaoskey.c +@@ -444,9 +444,19 @@ static ssize_t chaoskey_read(struct file *file, + goto bail; + mutex_unlock(&dev->rng_lock); + +- result = mutex_lock_interruptible(&dev->lock); +- if (result) +- goto bail; ++ if (file->f_flags & O_NONBLOCK) { ++ result = mutex_trylock(&dev->lock); ++ if (result == 0) { ++ result = -EAGAIN; ++ goto bail; ++ } else { ++ result = 0; ++ } ++ } else { ++ result = mutex_lock_interruptible(&dev->lock); ++ if (result) ++ goto bail; ++ } + if (dev->valid == dev->used) { + result = _chaoskey_fill(dev); + if (result < 0) { +-- +2.51.0 + diff --git a/queue-6.6/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch b/queue-6.6/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch new file mode 100644 index 0000000000..462a3eafdd --- /dev/null +++ b/queue-6.6/usb-dwc2-disable-platform-lowlevel-hw-resources-duri.patch @@ -0,0 +1,45 @@ +From 0ba546d0408561319385b4a3bed57ea8cd8f6e56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 29 Jun 2025 17:46:55 +0800 +Subject: usb: dwc2: disable platform lowlevel hw resources during shutdown + +From: Jisheng Zhang + +[ Upstream commit 7481a97c5f49f10c7490bb990d0e863f23b9bb71 ] + +On some SoC platforms, in shutdown stage, most components' power is cut +off, but there's still power supply to the so called always-on +domain, so if the dwc2's regulator is from the always-on domain, we +need to explicitly disable it to save power. + +Disable platform lowlevel hw resources such as phy, clock and +regulators etc. in device shutdown hook to reduce non-necessary power +consumption when the platform enters shutdown stage. + +Signed-off-by: Jisheng Zhang +Acked-by: Minas Harutyunyan +Link: https://lore.kernel.org/r/20250629094655.747-1-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: b6ebcfdcac40 ("usb: dwc2: fix hang during shutdown if set as peripheral") +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index c1b7209b94836..79ce88b5f07d9 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -371,6 +371,9 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + + dwc2_disable_global_interrupts(hsotg); + synchronize_irq(hsotg->irq); ++ ++ if (hsotg->ll_hw_enabled) ++ dwc2_lowlevel_hw_disable(hsotg); + } + + /** +-- +2.51.0 + diff --git a/queue-6.6/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch b/queue-6.6/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch new file mode 100644 index 0000000000..6e6db55968 --- /dev/null +++ b/queue-6.6/usb-dwc2-fix-hang-during-shutdown-if-set-as-peripher.patch @@ -0,0 +1,56 @@ +From 3a4f81cc93de01f413a4eefb06644242a638906d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:02 +0800 +Subject: usb: dwc2: fix hang during shutdown if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit b6ebcfdcac40a27953f052e4269ce75a18825ffc ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But dwc2_driver_shutdown() tries to disable the interrupts on HW IP +level. This would result in hang during shutdown if dwc2 is configured +as peripheral mode. + +Fix this hang by only disable and sync irq when lowlevel hw is enabled. + +Fixes: 4fdf228cdf69 ("usb: dwc2: Fix shutdown callback in platform") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-2-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index 79ce88b5f07d9..fad6f68f86bd6 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -369,11 +369,11 @@ static void dwc2_driver_shutdown(struct platform_device *dev) + { + struct dwc2_hsotg *hsotg = platform_get_drvdata(dev); + +- dwc2_disable_global_interrupts(hsotg); +- synchronize_irq(hsotg->irq); +- +- if (hsotg->ll_hw_enabled) ++ if (hsotg->ll_hw_enabled) { ++ dwc2_disable_global_interrupts(hsotg); ++ synchronize_irq(hsotg->irq); + dwc2_lowlevel_hw_disable(hsotg); ++ } + } + + /** +-- +2.51.0 + diff --git a/queue-6.6/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch b/queue-6.6/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch new file mode 100644 index 0000000000..63b7a8d7a7 --- /dev/null +++ b/queue-6.6/usb-dwc2-fix-hang-during-suspend-if-set-as-periphera.patch @@ -0,0 +1,66 @@ +From bcf9050374fb4d731a90b796c213c9bfba0727a4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 4 Nov 2025 08:25:03 +0800 +Subject: usb: dwc2: fix hang during suspend if set as peripheral + +From: Jisheng Zhang + +[ Upstream commit 2b94b054ac4974ad2f89f7f7461840c851933adb ] + +dwc2 on most platforms needs phy controller, clock and power supply. +All of them must be enabled/activated to properly operate. If dwc2 +is configured as peripheral mode, then all the above three hardware +resources are disabled at the end of the probe: + + /* Gadget code manages lowlevel hw on its own */ + if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) + dwc2_lowlevel_hw_disable(hsotg); + +But the dwc2_suspend() tries to read the dwc2's reg to check whether +is_device_mode or not, this would result in hang during suspend if dwc2 +is configured as peripheral mode. + +Fix this hang by bypassing suspend/resume if lowlevel hw isn't +enabled. + +Fixes: 09a75e857790 ("usb: dwc2: refactor common low-level hw code to platform.c") +Signed-off-by: Jisheng Zhang +Link: https://patch.msgid.link/20251104002503.17158-3-jszhang@kernel.org +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/dwc2/platform.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c +index fad6f68f86bd6..e80982c817d7d 100644 +--- a/drivers/usb/dwc2/platform.c ++++ b/drivers/usb/dwc2/platform.c +@@ -649,9 +649,13 @@ static int dwc2_driver_probe(struct platform_device *dev) + static int __maybe_unused dwc2_suspend(struct device *dev) + { + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); +- bool is_device_mode = dwc2_is_device_mode(dwc2); ++ bool is_device_mode; + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ ++ is_device_mode = dwc2_is_device_mode(dwc2); + if (is_device_mode) + dwc2_hsotg_suspend(dwc2); + +@@ -702,6 +706,9 @@ static int __maybe_unused dwc2_resume(struct device *dev) + struct dwc2_hsotg *dwc2 = dev_get_drvdata(dev); + int ret = 0; + ++ if (!dwc2->ll_hw_enabled) ++ return 0; ++ + if (dwc2->phy_off_for_suspend && dwc2->ll_hw_enabled) { + ret = __dwc2_lowlevel_hw_enable(dwc2); + if (ret) +-- +2.51.0 + diff --git a/queue-6.6/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch b/queue-6.6/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch new file mode 100644 index 0000000000..4826b5bcff --- /dev/null +++ b/queue-6.6/usb-fix-descriptor-count-when-handling-invalid-mbim-.patch @@ -0,0 +1,48 @@ +From 5a36d135c00c66a39bb142dbcd888c4f4fd0d430 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 28 Sep 2025 14:56:11 -0400 +Subject: USB: Fix descriptor count when handling invalid MBIM extended + descriptor + +From: Seungjin Bae + +[ Upstream commit 5570ad1423ee60f6e972dadb63fb2e5f90a54cbe ] + +In cdc_parse_cdc_header(), the check for the USB_CDC_MBIM_EXTENDED_TYPE +descriptor was using 'break' upon detecting an invalid length. + +This was incorrect because 'break' only exits the switch statement, +causing the code to fall through to cnt++, thus incorrectly +incrementing the count of parsed descriptors for a descriptor that was +actually invalid and being discarded. + +This patch changes 'break' to 'goto next_desc;' to ensure that the +logic skips the counter increment and correctly proceeds to the next +descriptor in the buffer. This maintains an accurate count of only +the successfully parsed descriptors. + +Fixes: e4c6fb7794982 ("usbnet: move the CDC parser into USB core") +Signed-off-by: Seungjin Bae +Link: https://lore.kernel.org/r/20250928185611.764589-1-eeodqql09@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/core/message.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c +index 077dfe48d01c1..5a5dfbf995e3a 100644 +--- a/drivers/usb/core/message.c ++++ b/drivers/usb/core/message.c +@@ -2428,7 +2428,7 @@ int cdc_parse_cdc_header(struct usb_cdc_parsed_header *hdr, + break; + case USB_CDC_MBIM_EXTENDED_TYPE: + if (elength < sizeof(struct usb_cdc_mbim_extended_desc)) +- break; ++ goto next_desc; + hdr->usb_cdc_mbim_extended_desc = + (struct usb_cdc_mbim_extended_desc *)buffer; + break; +-- +2.51.0 + diff --git a/queue-6.6/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch b/queue-6.6/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch new file mode 100644 index 0000000000..845dfed06c --- /dev/null +++ b/queue-6.6/usb-raw-gadget-cap-raw_io-transfer-length-to-kmalloc.patch @@ -0,0 +1,62 @@ +From 9dad4f805c4112914321152ada0c7b80e97957bb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 28 Oct 2025 22:26:57 +0530 +Subject: usb: raw-gadget: cap raw_io transfer length to KMALLOC_MAX_SIZE + +From: Gopi Krishna Menon + +[ Upstream commit a5160af78be7fcf3ade6caab0a14e349560c96d7 ] + +The previous commit removed the PAGE_SIZE limit on transfer length of +raw_io buffer in order to avoid any problems with emulating USB devices +whose full configuration descriptor exceeds PAGE_SIZE in length. However +this also removes the upperbound on user supplied length, allowing very +large values to be passed to the allocator. + +syzbot on fuzzing the transfer length with very large value (1.81GB) +results in kmalloc() to fall back to the page allocator, which triggers +a kernel warning as the page allocator cannot handle allocations more +than MAX_PAGE_ORDER/KMALLOC_MAX_SIZE. + +Since there is no limit imposed on the size of buffer for both control +and non control transfers, cap the raw_io transfer length to +KMALLOC_MAX_SIZE and return -EINVAL for larger transfer length to +prevent any warnings from the page allocator. + +Fixes: 37b9dd0d114a ("usb: raw-gadget: do not limit transfer length") +Tested-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Reported-by: syzbot+d8fd35fa6177afa8c92b@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/all/68fc07a0.a70a0220.3bf6c6.01ab.GAE@google.com/ +Signed-off-by: Gopi Krishna Menon +Reviewed-by: Andrey Konovalov +Link: https://patch.msgid.link/20251028165659.50962-1-krishnagopi487@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +--- + drivers/usb/gadget/legacy/raw_gadget.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/usb/gadget/legacy/raw_gadget.c b/drivers/usb/gadget/legacy/raw_gadget.c +index 2deab4a6030d7..8aa1a8408ae33 100644 +--- a/drivers/usb/gadget/legacy/raw_gadget.c ++++ b/drivers/usb/gadget/legacy/raw_gadget.c +@@ -39,6 +39,7 @@ MODULE_LICENSE("GPL"); + + static DEFINE_IDA(driver_id_numbers); + #define DRIVER_DRIVER_NAME_LENGTH_MAX 32 ++#define USB_RAW_IO_LENGTH_MAX KMALLOC_MAX_SIZE + + #define RAW_EVENT_QUEUE_SIZE 16 + +@@ -620,6 +621,8 @@ static void *raw_alloc_io_data(struct usb_raw_ep_io *io, void __user *ptr, + return ERR_PTR(-EINVAL); + if (!usb_raw_io_flags_valid(io->flags)) + return ERR_PTR(-EINVAL); ++ if (io->length > USB_RAW_IO_LENGTH_MAX) ++ return ERR_PTR(-EINVAL); + if (get_from_user) + data = memdup_user(ptr + sizeof(*io), io->length); + else { +-- +2.51.0 + diff --git a/queue-6.6/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch b/queue-6.6/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch new file mode 100644 index 0000000000..fad144b740 --- /dev/null +++ b/queue-6.6/vdpa-pds-use-pe-for-err_ptr-in-event-handler-registr.patch @@ -0,0 +1,40 @@ +From 87bf7996488981ea31db158a40bdf5e15ad97f64 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 18 Oct 2025 10:46:46 -0700 +Subject: vdpa/pds: use %pe for ERR_PTR() in event handler registration + +From: Alok Tiwari + +[ Upstream commit 731ca4a4cc52fd5c5ae309edcfd2d7e54ece3321 ] + +Use %pe instead of %ps when printing ERR_PTR() values. %ps is intended +for string pointers, while %pe correctly prints symbolic error names +for error pointers returned via ERR_PTR(). +This shows the returned error value more clearly. + +Fixes: 67f27b8b3a34 ("pds_vdpa: subscribe to the pds_core events") +Signed-off-by: Alok Tiwari +Reviewed-by: Brett Creeley +Signed-off-by: Michael S. Tsirkin +Message-Id: <20251018174705.1511982-1-alok.a.tiwari@oracle.com> +Signed-off-by: Sasha Levin +--- + drivers/vdpa/pds/vdpa_dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/vdpa/pds/vdpa_dev.c b/drivers/vdpa/pds/vdpa_dev.c +index 25c0fe5ec3d5d..744739a708b25 100644 +--- a/drivers/vdpa/pds/vdpa_dev.c ++++ b/drivers/vdpa/pds/vdpa_dev.c +@@ -51,7 +51,7 @@ static int pds_vdpa_register_event_handler(struct pds_vdpa_device *pdsv) + err = pdsc_register_notify(nb); + if (err) { + nb->notifier_call = NULL; +- dev_err(dev, "failed to register pds event handler: %ps\n", ++ dev_err(dev, "failed to register pds event handler: %pe\n", + ERR_PTR(err)); + return -EINVAL; + } +-- +2.51.0 + diff --git a/queue-6.6/virtio-fix-typo-in-virtio_device_ready-comment.patch b/queue-6.6/virtio-fix-typo-in-virtio_device_ready-comment.patch new file mode 100644 index 0000000000..e49b5983c6 --- /dev/null +++ b/queue-6.6/virtio-fix-typo-in-virtio_device_ready-comment.patch @@ -0,0 +1,36 @@ +From aefcddb652ff561831ad954456f1060570cddccb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:31 -0500 +Subject: virtio: fix typo in virtio_device_ready() comment + +From: Michael S. Tsirkin + +[ Upstream commit 361173f95ae4b726ebbbf0bd594274f5576c4abc ] + +"coherenct" -> "coherent" + +Fixes: 8b4ec69d7e09 ("virtio: harden vring IRQ") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 2b3438de2c4d4..84a9fd21df3e8 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -288,7 +288,7 @@ void virtio_device_ready(struct virtio_device *dev) + * specific set_status() method. + * + * A well behaved device will only notify a virtqueue after +- * DRIVER_OK, this means the device should "see" the coherenct ++ * DRIVER_OK, this means the device should "see" the coherent + * memory write that set vq->broken as false which is done by + * the driver when it sees DRIVER_OK, then the following + * driver's vring_interrupt() will see vq->broken as false so +-- +2.51.0 + diff --git a/queue-6.6/virtio-fix-virtqueue_set_affinity-docs.patch b/queue-6.6/virtio-fix-virtqueue_set_affinity-docs.patch new file mode 100644 index 0000000000..f14c1d9fc1 --- /dev/null +++ b/queue-6.6/virtio-fix-virtqueue_set_affinity-docs.patch @@ -0,0 +1,36 @@ +From 9ef9365c342d65f2a9def309a55f7de4d8490a72 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:43 -0500 +Subject: virtio: fix virtqueue_set_affinity() docs + +From: Michael S. Tsirkin + +[ Upstream commit 43236d8bbafff94b423afecc4a692dd90602d426 ] + +Rewrite the comment for better grammar and clarity. + +Fixes: 75a0a52be3c2 ("virtio: introduce an API to set affinity for a virtqueue") +Message-Id: +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index f106d3177476b..7528255068fd8 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -310,7 +310,7 @@ const char *virtio_bus_name(struct virtio_device *vdev) + * @vq: the virtqueue + * @cpu_mask: the cpu mask + * +- * Pay attention the function are best-effort: the affinity hint may not be set ++ * Note that this function is best-effort: the affinity hint may not be set + * due to config support, irq type and sharing. + * + */ +-- +2.51.0 + diff --git a/queue-6.6/virtio-fix-whitespace-in-virtio_config_ops.patch b/queue-6.6/virtio-fix-whitespace-in-virtio_config_ops.patch new file mode 100644 index 0000000000..21068291ba --- /dev/null +++ b/queue-6.6/virtio-fix-whitespace-in-virtio_config_ops.patch @@ -0,0 +1,37 @@ +From 06323f1ace88aa8442715c7d4b69145f96c0940d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 04:34:34 -0500 +Subject: virtio: fix whitespace in virtio_config_ops + +From: Michael S. Tsirkin + +[ Upstream commit 7831791e77a1cd29528d4dc336ce14466aef5ba6 ] + +The finalize_features documentation uses a tab between words. +Use space instead. + +Fixes: d16c0cd27331 ("docs: driver-api: virtio: virtio on Linux") +Message-Id: <39d7685c82848dc6a876d175e33a1407f6ab3fc1.1763026134.git.mst@redhat.com> +Acked-by: Jason Wang +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Sasha Levin +--- + include/linux/virtio_config.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/linux/virtio_config.h b/include/linux/virtio_config.h +index 84a9fd21df3e8..f106d3177476b 100644 +--- a/include/linux/virtio_config.h ++++ b/include/linux/virtio_config.h +@@ -71,7 +71,7 @@ typedef void vq_callback_t(struct virtqueue *); + * vdev: the virtio_device + * This sends the driver feature bits to the device: it can change + * the dev->feature bits if it wants. +- * Note that despite the name this can be called any number of ++ * Note that despite the name this can be called any number of + * times. + * Returns 0 on success or error status + * @bus_name: return the bus name associated with the device (optional) +-- +2.51.0 + diff --git a/queue-6.6/virtio_vdpa-fix-misleading-return-in-void-function.patch b/queue-6.6/virtio_vdpa-fix-misleading-return-in-void-function.patch new file mode 100644 index 0000000000..0a20d148c3 --- /dev/null +++ b/queue-6.6/virtio_vdpa-fix-misleading-return-in-void-function.patch @@ -0,0 +1,40 @@ +From e411ea845f921cec5166d8dfe17031b2887efa9c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 1 Oct 2025 12:16:50 -0700 +Subject: virtio_vdpa: fix misleading return in void function + +From: Alok Tiwari + +[ Upstream commit e40b6abe0b1247d43bc61942aa7534fca7209e44 ] + +virtio_vdpa_set_status() is declared as returning void, but it used +"return vdpa_set_status()" Since vdpa_set_status() also returns +void, the return statement is unnecessary and misleading. +Remove it. + +Fixes: c043b4a8cf3b ("virtio: introduce a vDPA based transport") +Signed-off-by: Alok Tiwari +Message-Id: <20251001191653.1713923-1-alok.a.tiwari@oracle.com> +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Signed-off-by: Sasha Levin +--- + drivers/virtio/virtio_vdpa.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/virtio/virtio_vdpa.c b/drivers/virtio/virtio_vdpa.c +index 06ce6d8c2e004..6855cc22ea96e 100644 +--- a/drivers/virtio/virtio_vdpa.c ++++ b/drivers/virtio/virtio_vdpa.c +@@ -93,7 +93,7 @@ static void virtio_vdpa_set_status(struct virtio_device *vdev, u8 status) + { + struct vdpa_device *vdpa = vd_get_vdpa(vdev); + +- return vdpa_set_status(vdpa, status); ++ vdpa_set_status(vdpa, status); + } + + static void virtio_vdpa_reset(struct virtio_device *vdev) +-- +2.51.0 + diff --git a/queue-6.6/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch b/queue-6.6/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch new file mode 100644 index 0000000000..7dafd76134 --- /dev/null +++ b/queue-6.6/watchdog-starfive-fix-resource-leak-in-probe-error-p.patch @@ -0,0 +1,51 @@ +From 1e477f1dbac69753ab1fd4fda90a5d60022dfcd7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Nov 2025 16:42:20 +0800 +Subject: watchdog: starfive: Fix resource leak in probe error path + +From: Haotian Zhang + +[ Upstream commit 5bcc5786a0cfa9249ccbe539833040a6285d0de3 ] + +If pm_runtime_put_sync() fails after watchdog_register_device() +succeeds, the probe function jumps to err_exit without +unregistering the watchdog device. This leaves the watchdog +registered in the subsystem while the driver fails to load, +resulting in a resource leak. + +Add a new error label err_unregister_wdt to properly unregister +the watchdog device. + +Fixes: 8bc22a2f1bf0 ("watchdog: starfive: Check pm_runtime_enabled() before decrementing usage counter") +Signed-off-by: Haotian Zhang +Reviewed-by: Wim Van Sebroeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/starfive-wdt.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c +index e4b344db38030..0606142ffc5e2 100644 +--- a/drivers/watchdog/starfive-wdt.c ++++ b/drivers/watchdog/starfive-wdt.c +@@ -498,12 +498,14 @@ static int starfive_wdt_probe(struct platform_device *pdev) + if (pm_runtime_enabled(&pdev->dev)) { + ret = pm_runtime_put_sync(&pdev->dev); + if (ret) +- goto err_exit; ++ goto err_unregister_wdt; + } + } + + return 0; + ++err_unregister_wdt: ++ watchdog_unregister_device(&wdt->wdd); + err_exit: + starfive_wdt_disable_clock(wdt); + pm_runtime_disable(&pdev->dev); +-- +2.51.0 + diff --git a/queue-6.6/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch b/queue-6.6/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch new file mode 100644 index 0000000000..e9dac0bf23 --- /dev/null +++ b/queue-6.6/watchdog-wdat_wdt-fix-acpi-table-leak-in-probe-funct.patch @@ -0,0 +1,160 @@ +From 696f073e54ebb799f3e9e32296ee404c7a87c3b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 10:30:32 +0800 +Subject: watchdog: wdat_wdt: Fix ACPI table leak in probe function + +From: Haotian Zhang + +[ Upstream commit 25c0b472eab8379683d4eef681185c104bed8ffd ] + +wdat_wdt_probe() calls acpi_get_table() to obtain the WDAT ACPI table but +never calls acpi_put_table() on any paths. This causes a permanent ACPI +table memory leak. + +Add a single cleanup path which calls acpi_put_table() to ensure +the ACPI table is always released. + +Fixes: 058dfc767008 ("ACPI / watchdog: Add support for WDAT hardware watchdog") +Suggested-by: Guenter Roeck +Signed-off-by: Haotian Zhang +Reviewed-by: Guenter Roeck +Signed-off-by: Guenter Roeck +Signed-off-by: Wim Van Sebroeck +Signed-off-by: Sasha Levin +--- + drivers/watchdog/wdat_wdt.c | 64 +++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 21 deletions(-) + +diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c +index 0ba99bed59fc4..02fbe05c37a08 100644 +--- a/drivers/watchdog/wdat_wdt.c ++++ b/drivers/watchdog/wdat_wdt.c +@@ -326,19 +326,27 @@ static int wdat_wdt_probe(struct platform_device *pdev) + return -ENODEV; + + wdat = devm_kzalloc(dev, sizeof(*wdat), GFP_KERNEL); +- if (!wdat) +- return -ENOMEM; ++ if (!wdat) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + regs = devm_kcalloc(dev, pdev->num_resources, sizeof(*regs), + GFP_KERNEL); +- if (!regs) +- return -ENOMEM; ++ if (!regs) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + /* WDAT specification wants to have >= 1ms period */ +- if (tbl->timer_period < 1) +- return -EINVAL; +- if (tbl->min_count > tbl->max_count) +- return -EINVAL; ++ if (tbl->timer_period < 1) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } ++ if (tbl->min_count > tbl->max_count) { ++ ret = -EINVAL; ++ goto out_put_table; ++ } + + wdat->period = tbl->timer_period; + wdat->wdd.min_timeout = DIV_ROUND_UP(wdat->period * tbl->min_count, 1000); +@@ -355,15 +363,20 @@ static int wdat_wdt_probe(struct platform_device *pdev) + res = &pdev->resource[i]; + if (resource_type(res) == IORESOURCE_MEM) { + reg = devm_ioremap_resource(dev, res); +- if (IS_ERR(reg)) +- return PTR_ERR(reg); ++ if (IS_ERR(reg)) { ++ ret = PTR_ERR(reg); ++ goto out_put_table; ++ } + } else if (resource_type(res) == IORESOURCE_IO) { + reg = devm_ioport_map(dev, res->start, 1); +- if (!reg) +- return -ENOMEM; ++ if (!reg) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + } else { + dev_err(dev, "Unsupported resource\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + regs[i] = reg; +@@ -385,8 +398,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + } + + instr = devm_kzalloc(dev, sizeof(*instr), GFP_KERNEL); +- if (!instr) +- return -ENOMEM; ++ if (!instr) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(&instr->node); + instr->entry = entries[i]; +@@ -417,7 +432,8 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + if (!instr->reg) { + dev_err(dev, "I/O resource not found\n"); +- return -EINVAL; ++ ret = -EINVAL; ++ goto out_put_table; + } + + instructions = wdat->instructions[action]; +@@ -425,8 +441,10 @@ static int wdat_wdt_probe(struct platform_device *pdev) + instructions = devm_kzalloc(dev, + sizeof(*instructions), + GFP_KERNEL); +- if (!instructions) +- return -ENOMEM; ++ if (!instructions) { ++ ret = -ENOMEM; ++ goto out_put_table; ++ } + + INIT_LIST_HEAD(instructions); + wdat->instructions[action] = instructions; +@@ -443,7 +461,7 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_enable_reboot(wdat); + if (ret) +- return ret; ++ goto out_put_table; + + platform_set_drvdata(pdev, wdat); + +@@ -460,12 +478,16 @@ static int wdat_wdt_probe(struct platform_device *pdev) + + ret = wdat_wdt_set_timeout(&wdat->wdd, timeout); + if (ret) +- return ret; ++ goto out_put_table; + + watchdog_set_nowayout(&wdat->wdd, nowayout); + watchdog_stop_on_reboot(&wdat->wdd); + watchdog_stop_on_unregister(&wdat->wdd); +- return devm_watchdog_register_device(dev, &wdat->wdd); ++ ret = devm_watchdog_register_device(dev, &wdat->wdd); ++ ++out_put_table: ++ acpi_put_table((struct acpi_table_header *)tbl); ++ return ret; + } + + static int wdat_wdt_suspend_noirq(struct device *dev) +-- +2.51.0 + diff --git a/queue-6.6/wifi-ath11k-fix-peer-he-mcs-assignment.patch b/queue-6.6/wifi-ath11k-fix-peer-he-mcs-assignment.patch new file mode 100644 index 0000000000..dab41529ef --- /dev/null +++ b/queue-6.6/wifi-ath11k-fix-peer-he-mcs-assignment.patch @@ -0,0 +1,94 @@ +From 7a23b48930c33ea68e39a0d146343b3f59ffe91d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 17 Oct 2025 09:49:00 +0800 +Subject: wifi: ath11k: fix peer HE MCS assignment + +From: Baochen Qiang + +[ Upstream commit 4a013ca2d490c73c40588d62712ffaa432046a04 ] + +In ath11k_wmi_send_peer_assoc_cmd(), peer's transmit MCS is sent to +firmware as receive MCS while peer's receive MCS sent as transmit MCS, +which goes against firmwire's definition. + +While connecting to a misbehaved AP that advertises 0xffff (meaning not +supported) for 160 MHz transmit MCS map, firmware crashes due to 0xffff +is assigned to he_mcs->rx_mcs_set field. + + Ext Tag: HE Capabilities + [...] + Supported HE-MCS and NSS Set + [...] + Rx and Tx MCS Maps 160 MHz + [...] + Tx HE-MCS Map 160 MHz: 0xffff + +Swap the assignment to fix this issue. + +As the HE rate control mask is meant to limit our own transmit MCS, it +needs to go via he_mcs->rx_mcs_set field. With the aforementioned swapping +done, change is needed as well to apply it to the peer's receive MCS. + +Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.41 +Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 + +Fixes: 61fe43e7216d ("ath11k: add support for setting fixed HE rate/gi/ltf") +Signed-off-by: Baochen Qiang +Reviewed-by: Vasanthakumar Thiagarajan +Link: https://patch.msgid.link/20251017-ath11k-mcs-assignment-v1-2-da40825c1783@oss.qualcomm.com +Signed-off-by: Jeff Johnson +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/ath/ath11k/mac.c | 4 ++-- + drivers/net/wireless/ath/ath11k/wmi.c | 7 +++++-- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c +index 2921be9bd530c..0937d725d4d0b 100644 +--- a/drivers/net/wireless/ath/ath11k/mac.c ++++ b/drivers/net/wireless/ath/ath11k/mac.c +@@ -2424,10 +2424,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + he_tx_mcs = v; + } + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_160); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_160); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_160] = v; + + arg->peer_he_mcs_count++; +@@ -2437,10 +2437,10 @@ static void ath11k_peer_assoc_h_he(struct ath11k *ar, + + default: + v = le16_to_cpu(he_cap->he_mcs_nss_supp.rx_mcs_80); ++ v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_rx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + v = le16_to_cpu(he_cap->he_mcs_nss_supp.tx_mcs_80); +- v = ath11k_peer_assoc_h_he_limit(v, he_mcs_mask); + arg->peer_he_tx_mcs_set[WMI_HECAP_TXRX_MCS_NSS_IDX_80] = v; + + arg->peer_he_mcs_count++; +diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c +index 16687223bdcba..f491aeb22a883 100644 +--- a/drivers/net/wireless/ath/ath11k/wmi.c ++++ b/drivers/net/wireless/ath/ath11k/wmi.c +@@ -2044,8 +2044,11 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar, + FIELD_PREP(WMI_TLV_LEN, + sizeof(*he_mcs) - TLV_HDR_SIZE); + +- he_mcs->rx_mcs_set = param->peer_he_tx_mcs_set[i]; +- he_mcs->tx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ /* firmware interprets mcs->rx_mcs_set field as peer's ++ * RX capability ++ */ ++ he_mcs->rx_mcs_set = param->peer_he_rx_mcs_set[i]; ++ he_mcs->tx_mcs_set = param->peer_he_tx_mcs_set[i]; + ptr += sizeof(*he_mcs); + } + +-- +2.51.0 + diff --git a/queue-6.6/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch b/queue-6.6/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch new file mode 100644 index 0000000000..313cee8c85 --- /dev/null +++ b/queue-6.6/wifi-cw1200-fix-potential-memory-leak-in-cw1200_bh_r.patch @@ -0,0 +1,43 @@ +From 3fcd93138b8c01b4dba98fcee2f23d614e548526 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 10 Nov 2025 23:23:15 +0530 +Subject: wifi: cw1200: Fix potential memory leak in cw1200_bh_rx_helper() + +From: Abdun Nihaal + +[ Upstream commit 5e88e864118c20e63a1571d0ff0a152e5d684959 ] + +In one of the error paths, the memory allocated for skb_rx is not freed. +Fix that by freeing it before returning. + +Fixes: a910e4a94f69 ("cw1200: add driver for the ST-E CW1100 & CW1200 WLAN chipsets") +Signed-off-by: Abdun Nihaal +Link: https://patch.msgid.link/20251110175316.106591-1-nihaal@cse.iitm.ac.in +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/st/cw1200/bh.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/wireless/st/cw1200/bh.c b/drivers/net/wireless/st/cw1200/bh.c +index 3b4ded2ac801c..37232ee220375 100644 +--- a/drivers/net/wireless/st/cw1200/bh.c ++++ b/drivers/net/wireless/st/cw1200/bh.c +@@ -317,10 +317,12 @@ static int cw1200_bh_rx_helper(struct cw1200_common *priv, + + if (wsm_id & 0x0400) { + int rc = wsm_release_tx_buffer(priv, 1); +- if (WARN_ON(rc < 0)) ++ if (WARN_ON(rc < 0)) { ++ dev_kfree_skb(skb_rx); + return rc; +- else if (rc > 0) ++ } else if (rc > 0) { + *tx = 1; ++ } + } + + /* cw1200_wsm_rx takes care on SKB livetime */ +-- +2.51.0 + diff --git a/queue-6.6/wifi-ieee80211-correct-fils-status-codes.patch b/queue-6.6/wifi-ieee80211-correct-fils-status-codes.patch new file mode 100644 index 0000000000..38de2f2843 --- /dev/null +++ b/queue-6.6/wifi-ieee80211-correct-fils-status-codes.patch @@ -0,0 +1,41 @@ +From 92103eb914ba9a6ae176f5bf5b6f031a2980626d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 24 Nov 2025 18:26:37 +0530 +Subject: wifi: ieee80211: correct FILS status codes + +From: Ria Thomas + +[ Upstream commit 24d4da5c2565313c2ad3c43449937a9351a64407 ] + +The FILS status codes are set to 108/109, but the IEEE 802.11-2020 +spec defines them as 112/113. Update the enum so it matches the +specification and keeps the kernel consistent with standard values. + +Fixes: a3caf7440ded ("cfg80211: Add support for FILS shared key authentication offload") +Signed-off-by: Ria Thomas +Reviewed-by: Jeff Johnson +Link: https://patch.msgid.link/20251124125637.3936154-1-ria.thomas@morsemicro.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + include/linux/ieee80211.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h +index 0ff10007eb1a5..38e3e81b880fb 100644 +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -3297,8 +3297,8 @@ enum ieee80211_statuscode { + WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL = 99, + WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT = 103, + /* 802.11ai */ +- WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 108, +- WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 109, ++ WLAN_STATUS_FILS_AUTHENTICATION_FAILURE = 112, ++ WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER = 113, + WLAN_STATUS_SAE_HASH_TO_ELEMENT = 126, + WLAN_STATUS_SAE_PK = 127, + }; +-- +2.51.0 + diff --git a/queue-6.6/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch b/queue-6.6/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch new file mode 100644 index 0000000000..10a9d1e4f9 --- /dev/null +++ b/queue-6.6/wifi-mac80211-fix-cmac-functions-not-handling-errors.patch @@ -0,0 +1,196 @@ +From 331be066e2dc836b225a24a734c51e40beefb5b9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 13 Nov 2025 22:05:07 +0800 +Subject: wifi: mac80211: fix CMAC functions not handling errors + +From: Chien Wong + +[ Upstream commit 353cda30d30e5dc7cacf8de5d2546724708ae3bb ] + +The called hash functions could fail thus we should check return values. + +Fixes: 26717828b75d ("mac80211: aes-cmac: switch to shash CMAC driver") +Signed-off-by: Chien Wong +Link: https://patch.msgid.link/20251113140511.48658-2-m@xv97.com +Signed-off-by: Johannes Berg +Signed-off-by: Sasha Levin +--- + net/mac80211/aes_cmac.c | 63 +++++++++++++++++++++++++++++------------ + net/mac80211/aes_cmac.h | 8 +++--- + net/mac80211/wpa.c | 20 +++++++------ + 3 files changed, 61 insertions(+), 30 deletions(-) + +diff --git a/net/mac80211/aes_cmac.c b/net/mac80211/aes_cmac.c +index 48c04f89de20a..65989c7dfc680 100644 +--- a/net/mac80211/aes_cmac.c ++++ b/net/mac80211/aes_cmac.c +@@ -22,50 +22,77 @@ + + static const u8 zero[CMAC_TLEN_256]; + +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + u8 out[AES_BLOCK_SIZE]; + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, data_len - 8 - CMAC_TLEN); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN); ++ err = crypto_shash_update(desc, data, ++ data_len - CMAC_TLEN); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN, out); +- ++ err = crypto_shash_finup(desc, zero, CMAC_TLEN, out); ++ if (err) ++ return err; + memcpy(mic, out, CMAC_TLEN); ++ ++ return 0; + } + +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic) ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic) + { ++ int err; + SHASH_DESC_ON_STACK(desc, tfm); + const __le16 *fc; + + desc->tfm = tfm; + +- crypto_shash_init(desc); +- crypto_shash_update(desc, aad, AAD_LEN); ++ err = crypto_shash_init(desc); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, aad, AAD_LEN); ++ if (err) ++ return err; + fc = (const __le16 *)aad; + if (ieee80211_is_beacon(*fc)) { + /* mask Timestamp field to zero */ +- crypto_shash_update(desc, zero, 8); +- crypto_shash_update(desc, data + 8, +- data_len - 8 - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, zero, 8); ++ if (err) ++ return err; ++ err = crypto_shash_update(desc, data + 8, ++ data_len - 8 - CMAC_TLEN_256); ++ if (err) ++ return err; + } else { +- crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ err = crypto_shash_update(desc, data, data_len - CMAC_TLEN_256); ++ if (err) ++ return err; + } +- crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); ++ return crypto_shash_finup(desc, zero, CMAC_TLEN_256, mic); + } + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], +diff --git a/net/mac80211/aes_cmac.h b/net/mac80211/aes_cmac.h +index 76817446fb838..f74150542142a 100644 +--- a/net/mac80211/aes_cmac.h ++++ b/net/mac80211/aes_cmac.h +@@ -11,10 +11,10 @@ + + struct crypto_shash *ieee80211_aes_cmac_key_setup(const u8 key[], + size_t key_len); +-void ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); +-void ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, +- const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); ++int ieee80211_aes_cmac_256(struct crypto_shash *tfm, const u8 *aad, ++ const u8 *data, size_t data_len, u8 *mic); + void ieee80211_aes_cmac_key_free(struct crypto_shash *tfm); + + #endif /* AES_CMAC_H */ +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 94dae7cb6dbd3..6223014e480c7 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -859,8 +859,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct ieee80211_tx_data *tx) + /* + * MIC = AES-128-CMAC(IGTK, AAD || Management Frame Body || MMIE, 64) + */ +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -902,8 +903,9 @@ ieee80211_crypto_aes_cmac_256_encrypt(struct ieee80211_tx_data *tx) + + /* MIC = AES-256-CMAC(IGTK, AAD || Management Frame Body || MMIE, 128) + */ +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mmie->mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mmie->mic)) ++ return TX_DROP; + + return TX_CONTINUE; + } +@@ -942,8 +944,9 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +@@ -992,8 +995,9 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + if (!(status->flag & RX_FLAG_DECRYPTED)) { + /* hardware didn't decrypt/verify MIC */ + bip_aad(skb, aad); +- ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, +- skb->data + 24, skb->len - 24, mic); ++ if (ieee80211_aes_cmac_256(key->u.aes_cmac.tfm, aad, ++ skb->data + 24, skb->len - 24, mic)) ++ return RX_DROP_U_DECRYPT_FAIL; + if (crypto_memneq(mic, mmie->mic, sizeof(mmie->mic))) { + key->u.aes_cmac.icverrors++; + return RX_DROP_U_MIC_FAIL; +-- +2.51.0 + diff --git a/queue-6.6/wifi-mac80211-remove-rx_drop_unusable.patch b/queue-6.6/wifi-mac80211-remove-rx_drop_unusable.patch new file mode 100644 index 0000000000..f3d30c807c --- /dev/null +++ b/queue-6.6/wifi-mac80211-remove-rx_drop_unusable.patch @@ -0,0 +1,502 @@ +From f87cc547707023fa776d4c1e868187b589ef5626 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 25 Sep 2023 17:25:09 +0200 +Subject: wifi: mac80211: remove RX_DROP_UNUSABLE + +From: Johannes Berg + +[ Upstream commit dccc9aa7ee84a9bed7a4840608829eba66f84cb9 ] + +Convert all instances of RX_DROP_UNUSABLE to indicate a +better reason, and then remove RX_DROP_UNUSABLE. + +Signed-off-by: Johannes Berg +Stable-dep-of: 353cda30d30e ("wifi: mac80211: fix CMAC functions not handling errors") +Signed-off-by: Sasha Levin +--- + net/mac80211/drop.h | 33 +++++++++++++++++++++++++++- + net/mac80211/rx.c | 52 ++++++++++++++++++++++----------------------- + net/mac80211/wep.c | 9 ++++---- + net/mac80211/wpa.c | 42 ++++++++++++++++++------------------ + 4 files changed, 84 insertions(+), 52 deletions(-) + +diff --git a/net/mac80211/drop.h b/net/mac80211/drop.h +index 1570fac8411f4..725a07a5b6145 100644 +--- a/net/mac80211/drop.h ++++ b/net/mac80211/drop.h +@@ -21,6 +21,38 @@ typedef unsigned int __bitwise ieee80211_rx_result; + R(RX_DROP_U_MIC_FAIL) \ + R(RX_DROP_U_REPLAY) \ + R(RX_DROP_U_BAD_MMIE) \ ++ R(RX_DROP_U_DUP) \ ++ R(RX_DROP_U_SPURIOUS) \ ++ R(RX_DROP_U_DECRYPT_FAIL) \ ++ R(RX_DROP_U_NO_KEY_ID) \ ++ R(RX_DROP_U_BAD_CIPHER) \ ++ R(RX_DROP_U_OOM) \ ++ R(RX_DROP_U_NONSEQ_PN) \ ++ R(RX_DROP_U_BAD_KEY_COLOR) \ ++ R(RX_DROP_U_BAD_4ADDR) \ ++ R(RX_DROP_U_BAD_AMSDU) \ ++ R(RX_DROP_U_BAD_AMSDU_CIPHER) \ ++ R(RX_DROP_U_INVALID_8023) \ ++ R(RX_DROP_U_RUNT_ACTION) \ ++ R(RX_DROP_U_UNPROT_ACTION) \ ++ R(RX_DROP_U_ACTION_UNKNOWN_SRC) \ ++ R(RX_DROP_U_REJECTED_ACTION_RESPONSE) \ ++ R(RX_DROP_U_EXPECT_DEFRAG_PROT) \ ++ R(RX_DROP_U_WEP_DEC_FAIL) \ ++ R(RX_DROP_U_NO_IV) \ ++ R(RX_DROP_U_NO_ICV) \ ++ R(RX_DROP_U_AP_RX_GROUPCAST) \ ++ R(RX_DROP_U_SHORT_MMIC) \ ++ R(RX_DROP_U_MMIC_FAIL) \ ++ R(RX_DROP_U_SHORT_TKIP) \ ++ R(RX_DROP_U_TKIP_FAIL) \ ++ R(RX_DROP_U_SHORT_CCMP) \ ++ R(RX_DROP_U_SHORT_CCMP_MIC) \ ++ R(RX_DROP_U_SHORT_GCMP) \ ++ R(RX_DROP_U_SHORT_GCMP_MIC) \ ++ R(RX_DROP_U_SHORT_CMAC) \ ++ R(RX_DROP_U_SHORT_CMAC256) \ ++ R(RX_DROP_U_SHORT_GMAC) \ + /* this line for the trailing \ - add before this */ + + /* having two enums allows for checking ieee80211_rx_result use with sparse */ +@@ -46,7 +78,6 @@ enum mac80211_drop_reason { + RX_CONTINUE = (__force ieee80211_rx_result)___RX_CONTINUE, + RX_QUEUED = (__force ieee80211_rx_result)___RX_QUEUED, + RX_DROP_MONITOR = (__force ieee80211_rx_result)___RX_DROP_MONITOR, +- RX_DROP_UNUSABLE = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE, + #define DEF(x) x = (__force ieee80211_rx_result)___ ## x, + MAC80211_DROP_REASONS_MONITOR(DEF) + MAC80211_DROP_REASONS_UNUSABLE(DEF) +diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c +index e6a0a65d4d43a..d27303b9f3a9b 100644 +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1436,7 +1436,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) + rx->sta->last_seq_ctrl[rx->seqno_idx] == hdr->seq_ctrl)) { + I802_DEBUG_INC(rx->local->dot11FrameDuplicateCount); + rx->link_sta->rx_stats.num_duplicates++; +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_DUP; + } else if (!(status->flag & RX_FLAG_AMSDU_MORE)) { + rx->sta->last_seq_ctrl[rx->seqno_idx] = hdr->seq_ctrl; + } +@@ -1490,7 +1490,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) + cfg80211_rx_spurious_frame(rx->sdata->dev, + hdr->addr2, + GFP_ATOMIC)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SPURIOUS; + + return RX_DROP_MONITOR; + } +@@ -1883,7 +1883,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + int keyidx; +- ieee80211_rx_result result = RX_DROP_UNUSABLE; ++ ieee80211_rx_result result = RX_DROP_U_DECRYPT_FAIL; + struct ieee80211_key *sta_ptk = NULL; + struct ieee80211_key *ptk_idx = NULL; + int mmie_keyidx = -1; +@@ -1933,7 +1933,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + keyid = ieee80211_get_keyid(rx->skb); + + if (unlikely(keyid < 0)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_NO_KEY_ID; + + ptk_idx = rcu_dereference(rx->sta->ptk[keyid]); + } +@@ -2038,7 +2038,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + keyidx = ieee80211_get_keyid(rx->skb); + + if (unlikely(keyidx < 0)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_NO_KEY_ID; + + /* check per-station GTK first, if multicast packet */ + if (is_multicast_ether_addr(hdr->addr1) && rx->link_sta) +@@ -2104,7 +2104,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) + result = ieee80211_crypto_gcmp_decrypt(rx); + break; + default: +- result = RX_DROP_UNUSABLE; ++ result = RX_DROP_U_BAD_CIPHER; + } + + /* the hdr variable is invalid after the decrypt handlers */ +@@ -2249,7 +2249,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + I802_DEBUG_INC(rx->local->rx_handlers_fragments); + + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + + /* + * skb_linearize() might change the skb->data and +@@ -2312,11 +2312,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; + + if (!requires_sequential_pn(rx, fc)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_NONSEQ_PN; + + /* Prevent mixed key and fragment cache attacks */ + if (entry->key_color != rx->key->color) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_KEY_COLOR; + + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { +@@ -2327,7 +2327,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + + rpn = rx->ccm_gcm.pn; + if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_REPLAY; + memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); + } else if (entry->is_protected && + (!rx->key || +@@ -2338,11 +2338,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + * if for TKIP Michael MIC should protect us, and WEP is a + * lost cause anyway. + */ +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_EXPECT_DEFRAG_PROT; + } else if (entry->is_protected && rx->key && + entry->key_color != rx->key->color && + (status->flag & RX_FLAG_DECRYPTED)) { +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_KEY_COLOR; + } + + skb_pull(rx->skb, ieee80211_hdrlen(fc)); +@@ -2361,7 +2361,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + GFP_ATOMIC))) { + I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); + __skb_queue_purge(&entry->skb_list); +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + } + } + while ((skb = __skb_dequeue(&entry->skb_list))) { +@@ -2910,10 +2910,10 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta + skb = NULL; + + if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + + if (skb_linearize(fwd_skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + } + + fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); +@@ -3010,7 +3010,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) + rx->sdata->vif.addr, + rx->sdata->vif.type, + data_offset, true)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_AMSDU; + + if (rx->sta->amsdu_mesh_control < 0) { + s8 valid = -1; +@@ -3085,21 +3085,21 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) + switch (rx->sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + if (!rx->sdata->u.vlan.sta) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_4ADDR; + break; + case NL80211_IFTYPE_STATION: + if (!rx->sdata->u.mgd.use_4addr) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_4ADDR; + break; + case NL80211_IFTYPE_MESH_POINT: + break; + default: +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_4ADDR; + } + } + + if (is_multicast_ether_addr(hdr->addr1) || !rx->sta) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_AMSDU; + + if (rx->key) { + /* +@@ -3112,7 +3112,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + case WLAN_CIPHER_SUITE_TKIP: +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_BAD_AMSDU_CIPHER; + default: + break; + } +@@ -3154,7 +3154,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) + + err = __ieee80211_data_to_8023(rx, &port_control); + if (unlikely(err)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_INVALID_8023; + + res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); + if (res != RX_CONTINUE) +@@ -3386,7 +3386,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) + /* drop too small action frames */ + if (ieee80211_is_action(mgmt->frame_control) && + rx->skb->len < IEEE80211_MIN_ACTION_SIZE) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_RUNT_ACTION; + + if (rx->sdata->vif.type == NL80211_IFTYPE_AP && + ieee80211_is_beacon(mgmt->frame_control) && +@@ -3408,7 +3408,7 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) + } + + if (ieee80211_drop_unencrypted_mgmt(rx)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_UNPROT_ACTION; + + return RX_CONTINUE; + } +@@ -3480,7 +3480,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx) + if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && + mgmt->u.action.category != WLAN_CATEGORY_SELF_PROTECTED && + mgmt->u.action.category != WLAN_CATEGORY_SPECTRUM_MGMT) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_ACTION_UNKNOWN_SRC; + + switch (mgmt->u.action.category) { + case WLAN_CATEGORY_HT: +@@ -3885,7 +3885,7 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx) + + /* do not return rejected action frames */ + if (mgmt->u.action.category & 0x80) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_REJECTED_ACTION_RESPONSE; + + nskb = skb_copy_expand(rx->skb, local->hw.extra_tx_headroom, 0, + GFP_ATOMIC); +diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c +index 9a6e11d7b4db6..5c01e121481ab 100644 +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -3,6 +3,7 @@ + * Software WEP encryption implementation + * Copyright 2002, Jouni Malinen + * Copyright 2003, Instant802 Networks, Inc. ++ * Copyright (C) 2023 Intel Corporation + */ + + #include +@@ -250,18 +251,18 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) + + if (!(status->flag & RX_FLAG_DECRYPTED)) { + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_WEP_DEC_FAIL; + } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { + if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + + IEEE80211_WEP_IV_LEN)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_NO_IV; + ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); + /* remove ICV */ + if (!(status->flag & RX_FLAG_ICV_STRIPPED) && + pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_NO_ICV; + } + + return RX_CONTINUE; +diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c +index 2d8e38b3bcb50..94dae7cb6dbd3 100644 +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -3,7 +3,7 @@ + * Copyright 2002-2004, Instant802 Networks, Inc. + * Copyright 2008, Jouni Malinen + * Copyright (C) 2016-2017 Intel Deutschland GmbH +- * Copyright (C) 2020-2022 Intel Corporation ++ * Copyright (C) 2020-2023 Intel Corporation + */ + + #include +@@ -142,7 +142,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + * group keys and only the AP is sending real multicast + * frames in the BSS. + */ +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_AP_RX_GROUPCAST; + } + + if (status->flag & RX_FLAG_MMIC_ERROR) +@@ -150,10 +150,10 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + + hdrlen = ieee80211_hdrlen(hdr->frame_control); + if (skb->len < hdrlen + MICHAEL_MIC_LEN) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_MMIC; + + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + hdr = (void *)skb->data; + + data = skb->data + hdrlen; +@@ -188,7 +188,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) + NL80211_KEYTYPE_PAIRWISE, + rx->key ? rx->key->conf.keyidx : -1, + NULL, GFP_ATOMIC); +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_MMIC_FAIL; + } + + static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) +@@ -276,11 +276,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + return RX_CONTINUE; + + if (!rx->sta || skb->len - hdrlen < 12) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_TKIP; + + /* it may be possible to optimize this a bit more */ + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + hdr = (void *)skb->data; + + /* +@@ -298,7 +298,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) + &rx->tkip.iv32, + &rx->tkip.iv16); + if (res != TKIP_DECRYPT_OK) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_TKIP_FAIL; + + /* Trim ICV */ + if (!(status->flag & RX_FLAG_ICV_STRIPPED)) +@@ -523,12 +523,12 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_CCMP; + if (status->flag & RX_FLAG_MIC_STRIPPED) + mic_len = 0; + } else { + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + } + + /* reload hdr - skb might have been reallocated */ +@@ -536,7 +536,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + + data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - mic_len; + if (!rx->sta || data_len < 0) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_CCMP; + + if (!(status->flag & RX_FLAG_PN_VALIDATED)) { + int res; +@@ -574,7 +574,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx, + + /* Remove CCMP header and MIC */ + if (pskb_trim(skb, skb->len - mic_len)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_CCMP_MIC; + memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen); + skb_pull(skb, IEEE80211_CCMP_HDR_LEN); + +@@ -719,12 +719,12 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + + if (status->flag & RX_FLAG_DECRYPTED) { + if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_GCMP_HDR_LEN)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_GCMP; + if (status->flag & RX_FLAG_MIC_STRIPPED) + mic_len = 0; + } else { + if (skb_linearize(rx->skb)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + } + + /* reload hdr - skb might have been reallocated */ +@@ -732,7 +732,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + + data_len = skb->len - hdrlen - IEEE80211_GCMP_HDR_LEN - mic_len; + if (!rx->sta || data_len < 0) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_GCMP; + + if (!(status->flag & RX_FLAG_PN_VALIDATED)) { + int res; +@@ -771,7 +771,7 @@ ieee80211_crypto_gcmp_decrypt(struct ieee80211_rx_data *rx) + + /* Remove GCMP header and MIC */ + if (pskb_trim(skb, skb->len - mic_len)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_GCMP_MIC; + memmove(skb->data + IEEE80211_GCMP_HDR_LEN, skb->data, hdrlen); + skb_pull(skb, IEEE80211_GCMP_HDR_LEN); + +@@ -924,7 +924,7 @@ ieee80211_crypto_aes_cmac_decrypt(struct ieee80211_rx_data *rx) + /* management frames are already linear */ + + if (skb->len < 24 + sizeof(*mmie)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_CMAC; + + mmie = (struct ieee80211_mmie *) + (skb->data + skb->len - sizeof(*mmie)); +@@ -974,13 +974,13 @@ ieee80211_crypto_aes_cmac_256_decrypt(struct ieee80211_rx_data *rx) + /* management frames are already linear */ + + if (skb->len < 24 + sizeof(*mmie)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_CMAC256; + + mmie = (struct ieee80211_mmie_16 *) + (skb->data + skb->len - sizeof(*mmie)); + if (mmie->element_id != WLAN_EID_MMIE || + mmie->length != sizeof(*mmie) - 2) +- return RX_DROP_UNUSABLE; /* Invalid MMIE */ ++ return RX_DROP_U_BAD_MMIE; /* Invalid MMIE */ + + bip_ipn_swap(ipn, mmie->sequence_number); + +@@ -1073,7 +1073,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) + /* management frames are already linear */ + + if (skb->len < 24 + sizeof(*mmie)) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_SHORT_GMAC; + + mmie = (struct ieee80211_mmie_16 *) + (skb->data + skb->len - sizeof(*mmie)); +@@ -1097,7 +1097,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct ieee80211_rx_data *rx) + + mic = kmalloc(GMAC_MIC_LEN, GFP_ATOMIC); + if (!mic) +- return RX_DROP_UNUSABLE; ++ return RX_DROP_U_OOM; + if (ieee80211_aes_gmac(key->u.aes_gmac.tfm, aad, nonce, + skb->data + 24, skb->len - 24, + mic) < 0 || +-- +2.51.0 + diff --git a/queue-6.6/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch b/queue-6.6/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch new file mode 100644 index 0000000000..7a9f63e0dd --- /dev/null +++ b/queue-6.6/wifi-rtl818x-fix-potential-memory-leaks-in-rtl8180_i.patch @@ -0,0 +1,65 @@ +From 6d70bc209ad3b4f7e954bae473435199aaaeb56d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 14 Nov 2025 15:15:26 +0530 +Subject: wifi: rtl818x: Fix potential memory leaks in rtl8180_init_rx_ring() + +From: Abdun Nihaal + +[ Upstream commit 9b5b9c042b30befc5b37e4539ace95af70843473 ] + +In rtl8180_init_rx_ring(), memory is allocated for skb packets and DMA +allocations in a loop. When an allocation fails, the previously +successful allocations are not freed on exit. + +Fix that by jumping to err_free_rings label on error, which calls +rtl8180_free_rx_ring() to free the allocations. Remove the free of +rx_ring in rtl8180_init_rx_ring() error path, and set the freed +priv->rx_buf entry to null, to avoid double free. + +Fixes: f653211197f3 ("Add rtl8180 wireless driver") +Signed-off-by: Abdun Nihaal +Reviewed-by: Ping-Ke Shih +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251114094527.79842-1-nihaal@cse.iitm.ac.in +Signed-off-by: Sasha Levin +--- + drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +index f6c25a52b69a9..fa8d8e216bd0f 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c +@@ -1023,9 +1023,6 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + dma_addr_t *mapping; + entry = priv->rx_ring + priv->rx_ring_sz*i; + if (!skb) { +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); + wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); + return -ENOMEM; + } +@@ -1037,9 +1034,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) + + if (dma_mapping_error(&priv->pdev->dev, *mapping)) { + kfree_skb(skb); +- dma_free_coherent(&priv->pdev->dev, +- priv->rx_ring_sz * 32, +- priv->rx_ring, priv->rx_ring_dma); ++ priv->rx_buf[i] = NULL; + wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n"); + return -ENOMEM; + } +@@ -1130,7 +1125,7 @@ static int rtl8180_start(struct ieee80211_hw *dev) + + ret = rtl8180_init_rx_ring(dev); + if (ret) +- return ret; ++ goto err_free_rings; + + for (i = 0; i < (dev->queues + 1); i++) + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) +-- +2.51.0 + diff --git a/queue-6.6/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch b/queue-6.6/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch new file mode 100644 index 0000000000..e070465f6b --- /dev/null +++ b/queue-6.6/wifi-rtl818x-rtl8187-fix-potential-buffer-underflow-.patch @@ -0,0 +1,90 @@ +From 969a3d485778c9cd97b2f85b922976965ee83165 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 Nov 2025 20:32:59 -0500 +Subject: wifi: rtl818x: rtl8187: Fix potential buffer underflow in + rtl8187_rx_cb() + +From: Seungjin Bae + +[ Upstream commit b647d2574e4583c2e3b0ab35568f60c88e910840 ] + +The rtl8187_rx_cb() calculates the rx descriptor header address +by subtracting its size from the skb tail pointer. +However, it does not validate if the received packet +(skb->len from urb->actual_length) is large enough to contain this +header. + +If a truncated packet is received, this will lead to a buffer +underflow, reading memory before the start of the skb data area, +and causing a kernel panic. + +Add length checks for both rtl8187 and rtl8187b descriptor headers +before attempting to access them, dropping the packet cleanly if the +check fails. + +Fixes: 6f7853f3cbe4 ("rtl8187: change rtl8187_dev.c to support RTL8187B (part 2)") +Signed-off-by: Seungjin Bae +Signed-off-by: Ping-Ke Shih +Link: https://patch.msgid.link/20251118013258.1789949-2-eeodqql09@gmail.com +Signed-off-by: Sasha Levin +--- + .../wireless/realtek/rtl818x/rtl8187/dev.c | 27 +++++++++++++------ + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +index f6528469022bf..70df4c0b939ca 100644 +--- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c +@@ -338,14 +338,16 @@ static void rtl8187_rx_cb(struct urb *urb) + spin_unlock_irqrestore(&priv->rx_queue.lock, f); + skb_put(skb, urb->actual_length); + +- if (unlikely(urb->status)) { +- dev_kfree_skb_irq(skb); +- return; +- } ++ if (unlikely(urb->status)) ++ goto free_skb; + + if (!priv->is_rtl8187b) { +- struct rtl8187_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + flags = le32_to_cpu(hdr->flags); + /* As with the RTL8187B below, the AGC is used to calculate + * signal strength. In this case, the scaling +@@ -355,8 +357,12 @@ static void rtl8187_rx_cb(struct urb *urb) + rx_status.antenna = (hdr->signal >> 7) & 1; + rx_status.mactime = le64_to_cpu(hdr->mac_time); + } else { +- struct rtl8187b_rx_hdr *hdr = +- (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); ++ struct rtl8187b_rx_hdr *hdr; ++ ++ if (skb->len < sizeof(struct rtl8187b_rx_hdr)) ++ goto free_skb; ++ ++ hdr = (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr)); + /* The Realtek datasheet for the RTL8187B shows that the RX + * header contains the following quantities: signal quality, + * RSSI, AGC, the received power in dB, and the measured SNR. +@@ -409,6 +415,11 @@ static void rtl8187_rx_cb(struct urb *urb) + skb_unlink(skb, &priv->rx_queue); + dev_kfree_skb_irq(skb); + } ++ return; ++ ++free_skb: ++ dev_kfree_skb_irq(skb); ++ return; + } + + static int rtl8187_init_urbs(struct ieee80211_hw *dev) +-- +2.51.0 + diff --git a/queue-6.6/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch b/queue-6.6/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch new file mode 100644 index 0000000000..bc09428512 --- /dev/null +++ b/queue-6.6/x86-boot-fix-page-table-access-in-5-level-to-4-level.patch @@ -0,0 +1,87 @@ +From 2627990f93d5611734147085cfed3ded4499b629 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Nov 2025 14:09:22 +0000 +Subject: x86/boot: Fix page table access in 5-level to 4-level paging + transition + +From: Usama Arif + +[ Upstream commit eb2266312507d7b757859e2227aa5c4ba6280ebe ] + +When transitioning from 5-level to 4-level paging, the existing code +incorrectly accesses page table entries by directly dereferencing CR3 and +applying PAGE_MASK. This approach has several issues: + +- __native_read_cr3() returns the raw CR3 register value, which on x86_64 + includes not just the physical address but also flags. Bits above the + physical address width of the system i.e. above __PHYSICAL_MASK_SHIFT) are + also not masked. + +- The PGD entry is masked by PAGE_SIZE which doesn't take into account the + higher bits such as _PAGE_BIT_NOPTISHADOW. + +Replace this with proper accessor functions: + +- native_read_cr3_pa(): Uses CR3_ADDR_MASK to additionally mask metadata out + of CR3 (like SME or LAM bits). All remaining bits are real address bits or + reserved and must be 0. + +- mask pgd value with PTE_PFN_MASK instead of PAGE_MASK, accounting for flags + above bit 51 (_PAGE_BIT_NOPTISHADOW in particular). Bits below 51, but above + the max physical address are reserved and must be 0. + +Fixes: e9d0e6330eb8 ("x86/boot/compressed/64: Prepare new top-level page table for trampoline") +Reported-by: Michael van der Westhuizen +Reported-by: Tobias Fleig +Co-developed-by: Kiryl Shutsemau +Signed-off-by: Kiryl Shutsemau +Signed-off-by: Usama Arif +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Ard Biesheuvel +Acked-by: Dave Hansen +Link: https://lore.kernel.org/r/a482fd68-ce54-472d-8df1-33d6ac9f6bb5@intel.com +Signed-off-by: Sasha Levin +--- + arch/x86/boot/compressed/pgtable_64.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c +index 15354673d3aa7..dc21b0d89d667 100644 +--- a/arch/x86/boot/compressed/pgtable_64.c ++++ b/arch/x86/boot/compressed/pgtable_64.c +@@ -2,6 +2,7 @@ + #include "misc.h" + #include + #include ++#include + #include + #include "pgtable.h" + #include "../string.h" +@@ -175,9 +176,10 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * For 4- to 5-level paging transition, set up current CR3 as + * the first and the only entry in a new top-level page table. + */ +- *trampoline_32bit = __native_read_cr3() | _PAGE_TABLE_NOENC; ++ *trampoline_32bit = native_read_cr3_pa() | _PAGE_TABLE_NOENC; + } else { +- unsigned long src; ++ u64 *new_cr3; ++ pgd_t *pgdp; + + /* + * For 5- to 4-level paging transition, copy page table pointed +@@ -187,8 +189,9 @@ asmlinkage void configure_5level_paging(struct boot_params *bp, void *pgtable) + * We cannot just point to the page table from trampoline as it + * may be above 4G. + */ +- src = *(unsigned long *)__native_read_cr3() & PAGE_MASK; +- memcpy(trampoline_32bit, (void *)src, PAGE_SIZE); ++ pgdp = (pgd_t *)native_read_cr3_pa(); ++ new_cr3 = (u64 *)(native_pgd_val(pgdp[0]) & PTE_PFN_MASK); ++ memcpy(trampoline_32bit, new_cr3, PAGE_SIZE); + } + + toggle_la57(trampoline_32bit); +-- +2.51.0 + diff --git a/queue-6.6/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch b/queue-6.6/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch new file mode 100644 index 0000000000..2c58ef4a27 --- /dev/null +++ b/queue-6.6/x86-dumpstack-prevent-kasan-false-positive-warnings-.patch @@ -0,0 +1,116 @@ +From 71894c4f20518cf42e4a54f9f7185b896a327bcd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 23 Oct 2025 09:06:32 +0000 +Subject: x86/dumpstack: Prevent KASAN false positive warnings in __show_regs() + +From: Tengda Wu + +[ Upstream commit ced37e9ceae50e4cb6cd058963bd315ec9afa651 ] + +When triggering a stack dump via sysrq (echo t > /proc/sysrq-trigger), +KASAN may report false-positive out-of-bounds access: + + BUG: KASAN: out-of-bounds in __show_regs+0x4b/0x340 + Call Trace: + dump_stack_lvl + print_address_description.constprop.0 + print_report + __show_regs + show_trace_log_lvl + sched_show_task + show_state_filter + sysrq_handle_showstate + __handle_sysrq + write_sysrq_trigger + proc_reg_write + vfs_write + ksys_write + do_syscall_64 + entry_SYSCALL_64_after_hwframe + +The issue occurs as follows: + + Task A (walk other tasks' stacks) Task B (running) + 1. echo t > /proc/sysrq-trigger + show_trace_log_lvl + regs = unwind_get_entry_regs() + show_regs_if_on_stack(regs) + 2. The stack value pointed by + `regs` keeps changing, and + so are the tags in its + KASAN shadow region. + __show_regs(regs) + regs->ax, regs->bx, ... + 3. hit KASAN redzones, OOB + +When task A walks task B's stack without suspending it, the continuous changes +in task B's stack (and corresponding KASAN shadow tags) may cause task A to +hit KASAN redzones when accessing obsolete values on the stack, resulting in +false positive reports. + +Simply stopping the task before unwinding is not a viable fix, as it would +alter the state intended to inspect. This is especially true for diagnosing +misbehaving tasks (e.g., in a hard lockup), where stopping might fail or hide +the root cause by changing the call stack. + +Therefore, fix this by disabling KASAN checks during asynchronous stack +unwinding, which is identified when the unwinding task does not match the +current task (task != current). + + [ bp: Align arguments on function's opening brace. ] + +Fixes: 3b3fa11bc700 ("x86/dumpstack: Print any pt_regs found on the stack") +Signed-off-by: Tengda Wu +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Andrey Ryabinin +Acked-by: Josh Poimboeuf +Link: https://patch.msgid.link/all/20251023090632.269121-1-wutengda@huaweicloud.com +Signed-off-by: Sasha Levin +--- + arch/x86/kernel/dumpstack.c | 23 +++++++++++++++++++++-- + 1 file changed, 21 insertions(+), 2 deletions(-) + +diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c +index 52dc5839d1e8e..0667d947d82bb 100644 +--- a/arch/x86/kernel/dumpstack.c ++++ b/arch/x86/kernel/dumpstack.c +@@ -183,8 +183,8 @@ static void show_regs_if_on_stack(struct stack_info *info, struct pt_regs *regs, + * in false positive reports. Disable instrumentation to avoid those. + */ + __no_kmsan_checks +-static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, +- unsigned long *stack, const char *log_lvl) ++static void __show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) + { + struct unwind_state state; + struct stack_info stack_info = {0}; +@@ -305,6 +305,25 @@ static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, + } + } + ++static void show_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, ++ unsigned long *stack, const char *log_lvl) ++{ ++ /* ++ * Disable KASAN to avoid false positives during walking another ++ * task's stacks, as values on these stacks may change concurrently ++ * with task execution. ++ */ ++ bool disable_kasan = task && task != current; ++ ++ if (disable_kasan) ++ kasan_disable_current(); ++ ++ __show_trace_log_lvl(task, regs, stack, log_lvl); ++ ++ if (disable_kasan) ++ kasan_enable_current(); ++} ++ + void show_stack(struct task_struct *task, unsigned long *sp, + const char *loglvl) + { +-- +2.51.0 +